mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1572838
- ensure osint commandline args are passed appropriately, r=mhowell,mossop
Differential Revision: https://phabricator.services.mozilla.com/D42311 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
c0db818712
commit
7b142a3c2b
@ -109,10 +109,7 @@ static mozilla::LauncherFlags ProcessCmdLine(int& aArgc, wchar_t* aArgv[]) {
|
||||
result |= mozilla::LauncherFlags::eWaitForBrowser;
|
||||
}
|
||||
|
||||
if (mozilla::CheckArg(
|
||||
aArgc, aArgv, L"no-deelevate", static_cast<const wchar_t**>(nullptr),
|
||||
mozilla::CheckArgFlag::CheckOSInt |
|
||||
mozilla::CheckArgFlag::RemoveArg) == mozilla::ARG_FOUND) {
|
||||
if (mozilla::CheckArg(aArgc, aArgv, L"no-deelevate") == mozilla::ARG_FOUND) {
|
||||
result |= mozilla::LauncherFlags::eNoDeelevate;
|
||||
}
|
||||
|
||||
@ -216,6 +213,8 @@ namespace mozilla {
|
||||
|
||||
Maybe<int> LauncherMain(int& argc, wchar_t* argv[],
|
||||
const StaticXREAppData& aAppData) {
|
||||
EnsureCommandlineSafe(argc, argv);
|
||||
|
||||
SetLauncherErrorAppData(aAppData);
|
||||
|
||||
if (CheckArg(argc, argv, L"log-launcher-error",
|
||||
|
@ -1254,8 +1254,7 @@ nsresult nsToolkitProfileService::SelectStartupProfile(
|
||||
|
||||
// Check the -profile command line argument. It accepts a single argument that
|
||||
// gives the path to use for the profile.
|
||||
ArgResult ar = CheckArg(*aArgc, aArgv, "profile", &arg,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
ArgResult ar = CheckArg(*aArgc, aArgv, "profile", &arg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR, "Error: argument --profile requires a path\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -1298,8 +1297,7 @@ nsresult nsToolkitProfileService::SelectStartupProfile(
|
||||
// Check the -createprofile command line argument. It accepts a single
|
||||
// argument that is either the name for the new profile or the name followed
|
||||
// by the path to use.
|
||||
ar = CheckArg(*aArgc, aArgv, "createprofile", &arg,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
ar = CheckArg(*aArgc, aArgv, "createprofile", &arg, CheckArgFlag::RemoveArg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --createprofile requires a profile name\n");
|
||||
@ -1369,14 +1367,7 @@ nsresult nsToolkitProfileService::SelectStartupProfile(
|
||||
return NS_ERROR_SHOW_PROFILE_MANAGER;
|
||||
}
|
||||
|
||||
ar = CheckArg(*aArgc, aArgv, "profilemanager", (const char**)nullptr,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --profilemanager is invalid when argument "
|
||||
"--osint is specified\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
ar = CheckArg(*aArgc, aArgv, "profilemanager");
|
||||
if (ar == ARG_FOUND) {
|
||||
return NS_ERROR_SHOW_PROFILE_MANAGER;
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ inline bool strimatch(const wchar_t* lowerstr, const wchar_t* mixedstr) {
|
||||
return internal::strimatch(&towlower, lowerstr, mixedstr);
|
||||
}
|
||||
|
||||
enum class FlagLiteral { osint, safemode };
|
||||
enum class FlagLiteral { osint, safemode, url };
|
||||
|
||||
template <typename CharT, FlagLiteral Literal>
|
||||
inline const CharT* GetLiteral();
|
||||
@ -106,11 +106,12 @@ inline const CharT* GetLiteral();
|
||||
|
||||
DECLARE_FLAG_LITERAL(osint, "osint")
|
||||
DECLARE_FLAG_LITERAL(safemode, "safe-mode")
|
||||
DECLARE_FLAG_LITERAL(url, "url")
|
||||
|
||||
enum class CheckArgFlag : uint32_t {
|
||||
None = 0,
|
||||
CheckOSInt = (1 << 0), // Retrun ARG_BAD if osint arg is also present.
|
||||
RemoveArg = (1 << 1) // Remove the argument from the argv array.
|
||||
// (1 << 0) Used to be CheckOSInt
|
||||
RemoveArg = (1 << 1) // Remove the argument from the argv array.
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CheckArgFlag)
|
||||
@ -188,19 +189,72 @@ inline ArgResult CheckArg(int& aArgc, CharT** aArgv, const CharT* aArg,
|
||||
++curarg;
|
||||
}
|
||||
|
||||
if ((aFlags & CheckArgFlag::CheckOSInt) && ar == ARG_FOUND) {
|
||||
ArgResult arOSInt =
|
||||
CheckArg(aArgc, aArgv, GetLiteral<CharT, FlagLiteral::osint>(),
|
||||
static_cast<const CharT**>(nullptr), CheckArgFlag::None);
|
||||
if (arOSInt == ARG_FOUND) {
|
||||
ar = ARG_BAD;
|
||||
#if defined(MOZILLA_INTERNAL_API)
|
||||
PR_fprintf(PR_STDERR, "Error: argument --osint is invalid\n");
|
||||
#endif // defined(MOZILLA_INTERNAL_API)
|
||||
return ar;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
inline void EnsureCommandlineSafe(int& aArgc, CharT** aArgv) {
|
||||
// We expect either no -osint, or the full commandline to be:
|
||||
// app -osint -url foo
|
||||
// If this varies, we abort to avoid abuse of other commandline handlers
|
||||
// from apps that do a poor job escaping links they give to the OS.
|
||||
|
||||
const CharT* osintLit = GetLiteral<CharT, FlagLiteral::osint>();
|
||||
|
||||
if (CheckArg(aArgc, aArgv, osintLit, static_cast<const CharT**>(nullptr),
|
||||
CheckArgFlag::None) == ARG_FOUND) {
|
||||
// There should be 4 items left (app name + -osint + -url + param)
|
||||
if (aArgc != 4) {
|
||||
exit(127);
|
||||
}
|
||||
|
||||
// The first should be osint.
|
||||
CharT* arg = aArgv[1];
|
||||
if (*arg != '-'
|
||||
#ifdef XP_WIN
|
||||
&& *arg != '/'
|
||||
#endif
|
||||
) {
|
||||
exit(127);
|
||||
}
|
||||
++arg;
|
||||
if (*arg == '-') {
|
||||
++arg;
|
||||
}
|
||||
if (!strimatch(osintLit, arg)) {
|
||||
exit(127);
|
||||
}
|
||||
// Strip it:
|
||||
RemoveArg(aArgc, aArgv + 1);
|
||||
|
||||
// Now only the -url bit should be left:
|
||||
arg = aArgv[1];
|
||||
if (*arg != '-'
|
||||
#ifdef XP_WIN
|
||||
&& *arg != '/'
|
||||
#endif
|
||||
) {
|
||||
exit(127);
|
||||
}
|
||||
++arg;
|
||||
if (*arg == '-') {
|
||||
++arg;
|
||||
}
|
||||
if (!strimatch(GetLiteral<CharT, FlagLiteral::url>(), arg)) {
|
||||
exit(127);
|
||||
}
|
||||
// The param after url shouldn't be another switch:
|
||||
arg = aArgv[2];
|
||||
if (*arg == '-'
|
||||
#ifdef XP_WIN
|
||||
|| *arg == '/'
|
||||
#endif
|
||||
) {
|
||||
exit(127);
|
||||
}
|
||||
}
|
||||
|
||||
return ar;
|
||||
// Either no osint, so nothing to do, or we ensured nothing nefarious was
|
||||
// passed.
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
@ -34,7 +34,7 @@ template <typename CharT>
|
||||
inline Maybe<bool> IsSafeModeRequested(
|
||||
int& aArgc, CharT* aArgv[],
|
||||
const SafeModeFlag aFlags = SafeModeFlag::Unset) {
|
||||
CheckArgFlag checkArgFlags = CheckArgFlag::CheckOSInt;
|
||||
CheckArgFlag checkArgFlags = CheckArgFlag::None;
|
||||
if (aFlags & SafeModeFlag::Unset) {
|
||||
checkArgFlags |= CheckArgFlag::RemoveArg;
|
||||
}
|
||||
|
@ -1975,26 +1975,12 @@ static nsresult SelectProfile(nsToolkitProfileService* aProfileSvc,
|
||||
|
||||
// reset-profile and migration args need to be checked before any profiles are
|
||||
// chosen below.
|
||||
ArgResult ar = CheckArg("reset-profile", nullptr,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --reset-profile is invalid when argument "
|
||||
"--osint is specified\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
ArgResult ar = CheckArg("reset-profile");
|
||||
if (ar == ARG_FOUND) {
|
||||
gDoProfileReset = true;
|
||||
}
|
||||
|
||||
ar = CheckArg("migration", nullptr,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --migration is invalid when argument --osint "
|
||||
"is specified\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
ar = CheckArg("migration");
|
||||
if (ar == ARG_FOUND) {
|
||||
gDoMigration = true;
|
||||
}
|
||||
@ -3104,8 +3090,7 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
|
||||
|
||||
// Check for application.ini overrides
|
||||
const char* override = nullptr;
|
||||
ar = CheckArg("override", &override,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
ar = CheckArg("override", &override);
|
||||
if (ar == ARG_BAD) {
|
||||
Output(true, "Incorrect number of arguments passed to --override");
|
||||
return 1;
|
||||
@ -3392,14 +3377,7 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
|
||||
// Handle --no-remote and --new-instance command line arguments. Setup
|
||||
// the environment to better accommodate other components and various
|
||||
// restart scenarios.
|
||||
ar = CheckArg("no-remote", nullptr,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --no-remote is invalid when argument --osint "
|
||||
"is specified\n");
|
||||
return 1;
|
||||
}
|
||||
ar = CheckArg("no-remote");
|
||||
if (ar == ARG_FOUND || EnvHasValue("MOZ_NO_REMOTE")) {
|
||||
mDisableRemoteClient = true;
|
||||
mDisableRemoteServer = true;
|
||||
@ -3408,14 +3386,7 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
|
||||
}
|
||||
}
|
||||
|
||||
ar = CheckArg("new-instance", nullptr,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --new-instance is invalid when argument "
|
||||
"--osint is specified\n");
|
||||
return 1;
|
||||
}
|
||||
ar = CheckArg("new-instance");
|
||||
if (ar == ARG_FOUND || EnvHasValue("MOZ_NEW_INSTANCE")) {
|
||||
mDisableRemoteClient = true;
|
||||
}
|
||||
@ -3426,15 +3397,7 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
|
||||
CheckArg("new-instance");
|
||||
#endif
|
||||
|
||||
ar = CheckArg("offline", nullptr,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --offline is invalid when argument --osint is "
|
||||
"specified\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ar = CheckArg("offline");
|
||||
if (ar || EnvHasValue("XRE_START_OFFLINE")) {
|
||||
mStartOffline = true;
|
||||
}
|
||||
@ -4619,9 +4582,15 @@ nsresult XREMain::XRE_mainRun() {
|
||||
* .app/Contents/Resources.
|
||||
*/
|
||||
int XREMain::XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig) {
|
||||
gArgc = argc;
|
||||
gArgv = argv;
|
||||
|
||||
EnsureCommandlineSafe(gArgc, gArgv);
|
||||
// DO NOT TOUCH THE COMMANDLINE ARGS BEFORE THIS!
|
||||
|
||||
ScopedLogging log;
|
||||
|
||||
mozilla::LogModule::Init(argc, argv);
|
||||
mozilla::LogModule::Init(gArgc, gArgv);
|
||||
|
||||
#ifdef MOZ_CODE_COVERAGE
|
||||
CodeCoverageHandler::Init();
|
||||
@ -4633,9 +4602,6 @@ int XREMain::XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig) {
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
gArgc = argc;
|
||||
gArgv = argv;
|
||||
|
||||
if (aConfig.appData) {
|
||||
mAppData = MakeUnique<XREAppData>(*aConfig.appData);
|
||||
} else {
|
||||
@ -4861,13 +4827,10 @@ nsresult XRE_InitCommandLine(int aArgc, char* aArgv[]) {
|
||||
recordreplay::parent::InitializeUIProcess(gArgc, gArgv);
|
||||
|
||||
const char* path = nullptr;
|
||||
ArgResult ar = CheckArg("greomni", &path,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
ArgResult ar = CheckArg("greomni", &path);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --greomni requires a path argument or the "
|
||||
"--osint argument was specified with the --appomni argument "
|
||||
"which is invalid\n");
|
||||
"Error: argument --greomni requires a path argument\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -4880,13 +4843,10 @@ nsresult XRE_InitCommandLine(int aArgc, char* aArgv[]) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
ar = CheckArg("appomni", &path,
|
||||
CheckArgFlag::CheckOSInt | CheckArgFlag::RemoveArg);
|
||||
ar = CheckArg("appomni", &path);
|
||||
if (ar == ARG_BAD) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"Error: argument --appomni requires a path argument or the "
|
||||
"--osint argument was specified with the --appomni argument "
|
||||
"which is invalid\n");
|
||||
"Error: argument --appomni requires a path argument\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user