diff --git a/src/utils/__tests__/PhutilUtilsTestCase.php b/src/utils/__tests__/PhutilUtilsTestCase.php --- a/src/utils/__tests__/PhutilUtilsTestCase.php +++ b/src/utils/__tests__/PhutilUtilsTestCase.php @@ -513,24 +513,35 @@ } public function testPhutilJSONDecode() { - $default = (object)array(); - - $cases = array( + $valid_cases = array( '{}' => array(), '[]' => array(), - '' => $default, - '"a"' => $default, - '{,}' => $default, - 'null' => $default, - '"null"' => $default, '[1, 2]' => array(1, 2), '{"a":"b"}' => array('a' => 'b'), ); - foreach ($cases as $input => $expect) { - $result = phutil_json_decode($input, $default); + foreach ($valid_cases as $input => $expect) { + $result = phutil_json_decode($input); $this->assertEqual($expect, $result, 'phutil_json_decode('.$input.')'); } + + $invalid_cases = array( + '', + '"a"', + '{,}', + 'null', + '"null"', + ); + + foreach ($invalid_cases as $input) { + $caught = null; + try { + phutil_json_decode($input); + } catch (Exception $ex) { + $caught = $ex; + } + $this->assertTrue($caught instanceof PhutilJSONParserException); + } } public function testCensorCredentials() { diff --git a/src/utils/utils.php b/src/utils/utils.php --- a/src/utils/utils.php +++ b/src/utils/utils.php @@ -1046,21 +1046,22 @@ /** - * Decode a JSON dictionary, or return a default value if the input does not - * decode or does not decode into a dictionary. + * Decode a JSON dictionary. * * @param string A string which ostensibly contains a JSON-encoded list or * dictionary. - * @param default? Optional default value to return if the string does not - * decode, or does not decode into a list or dictionary. - * @return mixed Decoded list/dictionary, or default value if string - * failed to decode. + * @return mixed Decoded list/dictionary. */ -function phutil_json_decode($string, $default = array()) { +function phutil_json_decode($string) { $result = @json_decode($string, true); + if (!is_array($result)) { - return $default; + // Failed to decode the JSON. Try to use @{class:PhutilJSONParser} instead. + // This will probably fail, but will throw a useful exception. + $parser = new PhutilJSONParser(); + $result = $parser->parse($string); } + return $result; }