X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FShell.h;h=0a58aa45da4c8a4ab4d3dfd4605f9838279ecae2;hb=c8aadaad37770dc4d1caf2bff239c604b51a6132;hp=56df3d278498dbd994bd2fe03f21fbe79a1beb2d;hpb=e69e359c24070c3b4ea2cd25f87b554e33b2a132;p=folly.git diff --git a/folly/Shell.h b/folly/Shell.h index 56df3d27..0a58aa45 100644 --- a/folly/Shell.h +++ b/folly/Shell.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -35,42 +36,58 @@ namespace folly { /** * Quotes an argument to make it suitable for use as shell command arguments. */ -std::string shellQuote(StringPiece argument) { - std::string quoted = "'"; - for (auto c : argument) { - if (c == '\'') { - quoted += "'\\''"; - } else { - quoted += c; - } +std::string shellQuote(StringPiece argument); + +namespace detail { +template +std::vector shellify( + StringPiece format, + Arguments&&... arguments) { + auto command = sformat( + format, + shellQuote(to(std::forward(arguments)))...); + return {"/bin/sh", "-c", command}; +} + +struct ShellCmdFormat { + StringPiece format; + template + std::vector operator()(Arguments&&... arguments) const { + return ::folly::detail::shellify( + format, std::forward(arguments)...); } - return quoted + "'"; +}; + +} // namespace detail + +inline namespace literals { +inline namespace shell_literals { +constexpr detail::ShellCmdFormat operator"" _shellify( + char const* name, + std::size_t length) { + return {folly::StringPiece(name, length)}; } +} // inline namespace shell_literals +} // inline namespace literals /** * Create argument array for `Subprocess()` for a process running in a * shell. * - * The shell to use is taken from the environment variable $SHELL, - * or /bin/sh if $SHELL is unset. - * - * The format string should always be a string literal to protect against - * shell injections. Arguments will automatically be escaped with `'`. + * The shell to use is always going to be `/bin/sh`. * - * TODO(dominik): find a way to ensure statically determined format strings. + * This is deprecated in favour of the user-defined-literal `_shellify` + * from namespace `folly::shell_literals` because that requires that the format + * string is a compile-time constant which can be inspected during code reviews */ template +FOLLY_DEPRECATED( + "Use `\"command {} {} ...\"_shellify(argument1, argument2 ...)` from " + "namespace `folly::literals::shell_literals`") std::vector shellify( - const StringPiece format, + StringPiece format, Arguments&&... arguments) { - const char* shell = getenv("SHELL"); - if (!shell) { - shell = "/bin/sh"; - } - auto command = sformat( - format, - shellQuote(to(std::forward(arguments)))...); - return {shell, "-c", command}; + return detail::shellify(format, std::forward(arguments)...); } } // folly