diff options
-rw-r--r-- | pym/portage/__init__.py | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 222130929..f47723141 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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 = { |