From bc5215075106ac7304f4e9e8ae0a8da9f5b96e6a Mon Sep 17 00:00:00 2001 From: mwilliams Date: Fri, 28 Jun 2013 07:47:43 -0700 Subject: [PATCH] Fix encoding of default arguments Default arguments with escape characters in were being over escaped. The old idl.php would first eval'd the string, then serialized the result. The new idl.cpp just serializes the original. We have to unencode it, then serialize. --- .../argument_handling/builtin_defaults.php | 8 ++++ .../builtin_defaults.php.expect | 2 + hphp/tools/bootstrap/idl.cpp | 39 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 hphp/test/slow/argument_handling/builtin_defaults.php create mode 100644 hphp/test/slow/argument_handling/builtin_defaults.php.expect diff --git a/hphp/test/slow/argument_handling/builtin_defaults.php b/hphp/test/slow/argument_handling/builtin_defaults.php new file mode 100644 index 000000000..8d8ad66ca --- /dev/null +++ b/hphp/test/slow/argument_handling/builtin_defaults.php @@ -0,0 +1,8 @@ + g_phpDefaults = { {"INT_MAX", "null"}, }; +static fbstring unescapeString(fbstring val) { + fbstring s = ""; + for (int i = 0; i < val.size(); ) { + int ch = val[i++]; + if (ch == '\\') { + if (i == val.size()) { + throw std::logic_error( + folly::format("Malformed string: '{0}'", val).str()); + } + ch = val[i++]; + switch (ch) { + case 'n': ch = '\n'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case '/': + case '"': + case '\'': + case '\\':break; + case '0': + ch = 0; + if (i == val.size() || + (!isdigit(val[i]) && val[i] != 'x' && val[i] != 'X')) { + break; + } + // fall through + default: + throw std::logic_error( + folly::format("Malformed string: '{0}'", val).str()); + break; + } + } + s += (char)ch; + } + return s; +} + /** * From idl/base.php:get_serialized_default() */ @@ -275,7 +311,8 @@ fbstring PhpParam::getDefaultSerialized() const { // Quoted string: "foo" if ((val.size() >= 2) && (val[0] == '"') && (val[val.size()-1] == '"')) { - return phpSerialize(val.substr(1, val.size() - 2)); + auto s = unescapeString(val.substr(1, val.size() - 2)); + return phpSerialize(s); } // Integers and Floats