bool TestExtString::test_trim() { VS(f_trim(" abc "), "abc"); return Count(true); }
Variant HHVM_FUNCTION(json_decode, const String& json, bool assoc /* = false */, int64_t depth /* = 512 */, int64_t options /* = 0 */) { json_set_last_error_code(json_error_codes::JSON_ERROR_NONE); if (json.empty()) { return init_null(); } const int64_t supported_options = k_JSON_FB_LOOSE | k_JSON_FB_COLLECTIONS | k_JSON_FB_STABLE_MAPS | k_JSON_BIGINT_AS_STRING; int64_t parser_options = options & supported_options; Variant z; if (JSON_parser(z, json.data(), json.size(), assoc, depth, parser_options)) { return z; } String trimmed = f_trim(json, "\t\n\r "); if (trimmed.size() == 4) { if (!strcasecmp(trimmed.data(), "null")) { json_set_last_error_code(json_error_codes::JSON_ERROR_NONE); return init_null(); } if (!strcasecmp(trimmed.data(), "true")) { json_set_last_error_code(json_error_codes::JSON_ERROR_NONE); return true; } } else if (trimmed.size() == 5 && !strcasecmp(trimmed.data(), "false")) { json_set_last_error_code(json_error_codes::JSON_ERROR_NONE); return false; } int64_t p; double d; DataType type = json.get()->isNumericWithVal(p, d, 0); if (type == KindOfInt64) { json_set_last_error_code(json_error_codes::JSON_ERROR_NONE); return p; } else if (type == KindOfDouble) { json_set_last_error_code(json_error_codes::JSON_ERROR_NONE); if ((options & k_JSON_BIGINT_AS_STRING) && (json.toInt64() == LLONG_MAX || json.toInt64() == LLONG_MIN) && errno == ERANGE) { // Overflow bool is_float = false; for (int i = (trimmed[0] == '-' ? 1 : 0); i < trimmed.size(); ++i) { if (trimmed[i] < '0' || trimmed[i] > '9') { is_float = true; break; } } if (!is_float) { return trimmed; } } return d; } char ch0 = json.charAt(0); if (json.size() > 1 && ch0 == '"' && json.charAt(json.size() - 1) == '"') { json_set_last_error_code(json_error_codes::JSON_ERROR_NONE); // Wrap the string in an array to allow the JSON_parser to handle // things like unicode escape sequences, then unwrap to get result String wrapped("["); wrapped += json + "]"; // Stick to a normal hhvm array for the wrapper const int64_t mask = ~(k_JSON_FB_COLLECTIONS | k_JSON_FB_STABLE_MAPS); if (JSON_parser(z, wrapped.data(), wrapped.size(), false, depth, parser_options & mask) && z.isArray()) { Array arr = z.toArray(); if ((arr.size() == 1) && arr.exists(0)) { return arr[0]; } // The input string could be something like: "foo","bar" // Which will parse inside the [] wrapper, but be invalid json_set_last_error_code(json_error_codes::JSON_ERROR_SYNTAX); } } if ((options & k_JSON_FB_LOOSE) && json.size() > 1 && ch0 == '\'' && json.charAt(json.size() - 1) == '\'') { json_set_last_error_code(json_error_codes::JSON_ERROR_NONE); return json.substr(1, json.size() - 2); } assert(json_get_last_error_code() != json_error_codes::JSON_ERROR_NONE); return init_null(); }