For portage.spawn() calls, use a _shell_quote() function to quote
authorZac Medico <zmedico@gentoo.org>
Sun, 2 Dec 2007 06:44:02 +0000 (06:44 -0000)
committerZac Medico <zmedico@gentoo.org>
Sun, 2 Dec 2007 06:44:02 +0000 (06:44 -0000)
the path of the binary since.

svn path=/main/trunk/; revision=8798

pym/portage/__init__.py

index 222130929dd8b5b0c4ed46dd9f778fb907b3f14c..f47723141dfa0a8ad0638ceb9ee8d0c362c7eaea 100644 (file)
@@ -2633,6 +2633,17 @@ class config(object):
                                        pass
                return self._selinux_enabled
 
+def _shell_quote(s):
+       """
+       Quote a string in double-quotes and use backslashes to
+       escape any backslashes, double-quotes, dollar signs, or
+       backquotes in the string.
+       """
+       for letter in "\\\"$`":
+               if letter in s:
+                       s = s.replace(letter, "\\" + letter)
+       return "\"%s\"" % s
+
 # In some cases, openpty can be slow when it fails. Therefore,
 # stop trying to use it after the first failure.
 _disable_openpty = False
@@ -3689,7 +3700,7 @@ def spawnebuild(mydo,actionmap,mysettings,debug,alwaysdep=0,logfile=None):
                        portage_bin_path = mysettings["PORTAGE_BIN_PATH"]
                        misc_sh_binary = os.path.join(portage_bin_path,
                                os.path.basename(MISC_SH_BINARY))
-                       mycommand = " ".join([misc_sh_binary,
+                       mycommand = " ".join([_shell_quote(misc_sh_binary),
                                "install_qa_check", "install_symlink_html_docs"])
                        qa_retval = spawn(mycommand, mysettings, debug=debug, logfile=logfile, **kwargs)
                        if qa_retval:
@@ -4274,7 +4285,8 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                mysettings["dbkey"] = ""
                                pr, pw = os.pipe()
                                fd_pipes = {0:0, 1:1, 2:2, 9:pw}
-                               mypids = spawn(ebuild_sh_binary + " depend", mysettings,
+                               mypids = spawn(_shell_quote(ebuild_sh_binary) + " depend",
+                                       mysettings,
                                        fd_pipes=fd_pipes, returnpid=True, droppriv=droppriv)
                                os.close(pw) # belongs exclusively to the child process now
                                maxbytes = 1024
@@ -4303,7 +4315,8 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                mysettings["dbkey"] = \
                                        os.path.join(mysettings.depcachedir, "aux_db_key_temp")
 
-                       return spawn(ebuild_sh_binary + " depend", mysettings,
+                       return spawn(_shell_quote(ebuild_sh_binary) + " depend",
+                               mysettings,
                                droppriv=droppriv)
 
                # Validate dependency metadata here to ensure that ebuilds with invalid
@@ -4385,7 +4398,9 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                        saved_env = None
                        if saved_env:
                                retval = os.system(
-                                       "bzip2 -dc '%s' > '%s'" % (saved_env, env_file))
+                                       "bzip2 -dc %s > %s" % \
+                                       (_shell_quote(saved_env),
+                                       _shell_quote(env_file)))
                                try:
                                        env_stat = os.stat(env_file)
                                except OSError, e:
@@ -4418,11 +4433,11 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                # if any of these are being called, handle them -- running them out of
                # the sandbox -- and stop now.
                if mydo in ["clean","cleanrm"]:
-                       return spawn(ebuild_sh_binary + " clean", mysettings,
+                       return spawn(_shell_quote(ebuild_sh_binary) + " clean", mysettings,
                                debug=debug, free=1, logfile=None)
                elif mydo == "help":
-                       return spawn(ebuild_sh_binary + " " + mydo, mysettings,
-                               debug=debug, free=1, logfile=logfile)
+                       return spawn(_shell_quote(ebuild_sh_binary) + " " + mydo,
+                               mysettings, debug=debug, free=1, logfile=logfile)
                elif mydo == "setup":
                        infodir = os.path.join(
                                mysettings["PORTAGE_BUILDDIR"], "build-info")
@@ -4430,7 +4445,8 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                """Load USE flags for setup phase of a binary package.
                                Ideally, the environment.bz2 would be used instead."""
                                mysettings.load_infodir(infodir)
-                       retval = spawn(ebuild_sh_binary + " " + mydo, mysettings,
+                       retval = spawn(
+                               _shell_quote(ebuild_sh_binary) + " " + mydo, mysettings,
                                debug=debug, free=1, logfile=logfile)
                        retval = exit_status_check(retval)
                        if secpass >= 2:
@@ -4441,13 +4457,15 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                                        filemode=060, filemask=0)
                        return retval
                elif mydo == "preinst":
-                       phase_retval = spawn(" ".join((ebuild_sh_binary, mydo)),
+                       phase_retval = spawn(
+                               _shell_quote(ebuild_sh_binary) + " " + mydo,
                                mysettings, debug=debug, free=1, logfile=logfile)
                        phase_retval = exit_status_check(phase_retval)
                        if phase_retval == os.EX_OK:
                                # Post phase logic and tasks that have been factored out of
                                # ebuild.sh.
-                               myargs = [misc_sh_binary, "preinst_bsdflags", "preinst_mask",
+                               myargs = [_shell_quote(misc_sh_binary),
+                                       "preinst_bsdflags", "preinst_mask",
                                        "preinst_sfperms", "preinst_selinux_labels",
                                        "preinst_suid_scan"]
                                _doebuild_exit_status_unlink(
@@ -4462,13 +4480,14 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                        return phase_retval
                elif mydo == "postinst":
                        mysettings.load_infodir(mysettings["O"])
-                       phase_retval = spawn(" ".join((ebuild_sh_binary, mydo)),
+                       phase_retval = spawn(
+                               _shell_quote(ebuild_sh_binary) + " " + mydo,
                                mysettings, debug=debug, free=1, logfile=logfile)
                        phase_retval = exit_status_check(phase_retval)
                        if phase_retval == os.EX_OK:
                                # Post phase logic and tasks that have been factored out of
                                # ebuild.sh.
-                               myargs = [misc_sh_binary, "postinst_bsdflags"]
+                               myargs = [_shell_quote(misc_sh_binary), "postinst_bsdflags"]
                                _doebuild_exit_status_unlink(
                                        mysettings.get("EBUILD_EXIT_STATUS_FILE"))
                                mysettings["EBUILD_PHASE"] = ""
@@ -4481,7 +4500,8 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                        return phase_retval
                elif mydo in ("prerm", "postrm", "config", "info"):
                        mysettings.load_infodir(mysettings["O"])
-                       retval =  spawn(ebuild_sh_binary + " " + mydo,
+                       retval =  spawn(
+                               _shell_quote(ebuild_sh_binary) + " " + mydo,
                                mysettings, debug=debug, free=1, logfile=logfile)
                        retval = exit_status_check(retval)
                        return retval
@@ -4617,8 +4637,8 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
 
                fakeroot = "fakeroot" in mysettings.features
 
-               ebuild_sh = ebuild_sh_binary + " %s"
-               misc_sh = misc_sh_binary + " dyn_%s"
+               ebuild_sh = _shell_quote(ebuild_sh_binary) + " %s"
+               misc_sh = _shell_quote(misc_sh_binary) + " dyn_%s"
 
                # args are for the to spawn function
                actionmap = {