diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:50:09 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:50:09 +0000 | 
| commit | f3fbd1c0586ff6ec7895991e6c28f61a503c36a8 (patch) | |
| tree | 48d008fd3df8c0e73271a4b18474e0aac6dbfe33 /source/Interpreter/Args.cpp | |
| parent | 2fc5d2d1dfaf623ce4e24cd8590565902f8c557c (diff) | |
Notes
Diffstat (limited to 'source/Interpreter/Args.cpp')
| -rw-r--r-- | source/Interpreter/Args.cpp | 100 | 
1 files changed, 86 insertions, 14 deletions
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp index 81e6b0aa1dbc..d90ef1d256a4 100644 --- a/source/Interpreter/Args.cpp +++ b/source/Interpreter/Args.cpp @@ -83,19 +83,22 @@ Args::~Args ()  }  void -Args::Dump (Stream *s) +Args::Dump (Stream &s, const char *label_name) const  { +    if (!label_name) +        return; +      const size_t argc = m_argv.size();      for (size_t i=0; i<argc; ++i)      { -        s->Indent(); +        s.Indent();          const char *arg_cstr = m_argv[i];          if (arg_cstr) -            s->Printf("argv[%zi]=\"%s\"\n", i, arg_cstr); +            s.Printf("%s[%zi]=\"%s\"\n", label_name, i, arg_cstr);          else -            s->Printf("argv[%zi]=NULL\n", i); +            s.Printf("%s[%zi]=NULL\n", label_name, i);      } -    s->EOL(); +    s.EOL();  }  bool @@ -575,8 +578,8 @@ Args::ParseOptions (Options &options)              }          }      } -    Mutex::Locker options_locker(NULL); -    OptionParser::Prepare(options_locker); +    std::unique_lock<std::mutex> lock; +    OptionParser::Prepare(lock);      int val;      while (1)      { @@ -887,14 +890,43 @@ Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t  }  const char * -Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg) +Args::GetShellSafeArgument (const FileSpec& shell, +                            const char *unsafe_arg, +                            std::string &safe_arg)  { +    struct ShellDescriptor +    { +        ConstString m_basename; +        const char* m_escapables; +    }; +     +    static ShellDescriptor g_Shells[] = { +        {ConstString("bash")," '\"<>()&"}, +        {ConstString("tcsh")," '\"<>()&$"}, +        {ConstString("sh")," '\"<>()&"} +    }; +     +    // safe minimal set +    const char* escapables = " '\""; +     +    if (auto basename = shell.GetFilename()) +    { +        for (const auto& Shell : g_Shells) +        { +            if (Shell.m_basename == basename) +            { +                escapables = Shell.m_escapables; +                break; +            } +        } +    } +      safe_arg.assign (unsafe_arg);      size_t prev_pos = 0;      while (prev_pos < safe_arg.size())      {          // Escape spaces and quotes -        size_t pos = safe_arg.find_first_of(" '\"", prev_pos); +        size_t pos = safe_arg.find_first_of(escapables, prev_pos);          if (pos != std::string::npos)          {              safe_arg.insert (pos, 1, '\\'); @@ -906,7 +938,6 @@ Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg)      return safe_arg.c_str();  } -  int64_t  Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)  {     @@ -1108,6 +1139,47 @@ Args::LongestCommonPrefix (std::string &common_prefix)      }  } +bool +Args::ContainsEnvironmentVariable(const char *env_var_name) const +{ +    // Validate args. +    if (!env_var_name) +        return false; + +    // Check each arg to see if it matches the env var name. +    for (size_t i = 0; i < GetArgumentCount(); ++i) +    { +        // Get the arg value. +        const char *argument_value = GetArgumentAtIndex(i); +        if (!argument_value) +            continue; + +        // Check if we are the "{env_var_name}={env_var_value}" style. +        const char *equal_p = strchr(argument_value, '='); +        if (equal_p) +        { +            if (strncmp(env_var_name, argument_value, +                        equal_p - argument_value) == 0) +            { +                // We matched. +                return true; +            } +        } +        else +        { +            // We're a simple {env_var_name}-style entry. +            if (strcmp(argument_value, env_var_name) == 0) +            { +                // We matched. +                return true; +            } +        } +    } + +    // We didn't find a match. +    return false; +} +  size_t  Args::FindArgumentIndexForOption (Option *long_options, int long_options_index)  { @@ -1190,8 +1262,8 @@ Args::ParseAliasOptions (Options &options,          }      } -    Mutex::Locker options_locker(NULL); -    OptionParser::Prepare(options_locker); +    std::unique_lock<std::mutex> lock; +    OptionParser::Prepare(lock);      int val;      while (1)      { @@ -1368,8 +1440,8 @@ Args::ParseArgsForCompletion          }      } -    Mutex::Locker options_locker(NULL); -    OptionParser::Prepare(options_locker); +    std::unique_lock<std::mutex> lock; +    OptionParser::Prepare(lock);      OptionParser::EnableError(false);      int val;  | 
