From 4484946cfd29d1d3f61c03825d812601038fa75c Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 11 Mar 2021 11:48:55 -0800 Subject: [PATCH] In JSON DocumentEngine, preserve the distinction between "{}" and "[]" Summary: Ref T13635. Currently, the JSON DocumentEngine uses "phutil_json_decode()", but this can confuse "{}" and "[]". Be more careful about how the JSON value is decoded, to preserve the distinction. Test Plan: {F8520479} Maniphest Tasks: T13635 Differential Revision: https://secure.phabricator.com/D21605 --- src/__phutil_library_map__.php | 2 ++ .../document/PhabricatorJSONDocumentEngine.php | 18 ++++++++++++++++++ ...habricatorDocumentEngineParserException.php | 4 ++++ 3 files changed, 24 insertions(+) create mode 100644 src/applications/files/document/exception/PhabricatorDocumentEngineParserException.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 065c588ddb..52e5f46bbf 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -3209,6 +3209,7 @@ phutil_register_library_map(array( 'PhabricatorDocumentEngineBlock' => 'applications/files/diff/PhabricatorDocumentEngineBlock.php', 'PhabricatorDocumentEngineBlockDiff' => 'applications/files/diff/PhabricatorDocumentEngineBlockDiff.php', 'PhabricatorDocumentEngineBlocks' => 'applications/files/diff/PhabricatorDocumentEngineBlocks.php', + 'PhabricatorDocumentEngineParserException' => 'applications/files/document/exception/PhabricatorDocumentEngineParserException.php', 'PhabricatorDocumentRef' => 'applications/files/document/PhabricatorDocumentRef.php', 'PhabricatorDocumentRenderingEngine' => 'applications/files/document/render/PhabricatorDocumentRenderingEngine.php', 'PhabricatorDoorkeeperApplication' => 'applications/doorkeeper/application/PhabricatorDoorkeeperApplication.php', @@ -9707,6 +9708,7 @@ phutil_register_library_map(array( 'PhabricatorDocumentEngineBlock' => 'Phobject', 'PhabricatorDocumentEngineBlockDiff' => 'Phobject', 'PhabricatorDocumentEngineBlocks' => 'Phobject', + 'PhabricatorDocumentEngineParserException' => 'Exception', 'PhabricatorDocumentRef' => 'Phobject', 'PhabricatorDocumentRenderingEngine' => 'Phobject', 'PhabricatorDoorkeeperApplication' => 'PhabricatorApplication', diff --git a/src/applications/files/document/PhabricatorJSONDocumentEngine.php b/src/applications/files/document/PhabricatorJSONDocumentEngine.php index 683f1746e6..42f4469ee6 100644 --- a/src/applications/files/document/PhabricatorJSONDocumentEngine.php +++ b/src/applications/files/document/PhabricatorJSONDocumentEngine.php @@ -31,6 +31,17 @@ final class PhabricatorJSONDocumentEngine try { $data = phutil_json_decode($raw_data); + // See T13635. "phutil_json_decode()" always turns JSON into a PHP array, + // and we lose the distinction between "{}" and "[]". This distinction is + // important when rendering a document. + $data = json_decode($raw_data, false); + if (!$data) { + throw new PhabricatorDocumentEngineParserException( + pht( + 'Failed to "json_decode(...)" JSON document after successfully '. + 'decoding it with "phutil_json_decode(...).')); + } + if (preg_match('/^\s*\[/', $raw_data)) { $content = id(new PhutilJSON())->encodeAsList($data); } else { @@ -47,6 +58,13 @@ final class PhabricatorJSONDocumentEngine 'This document is not valid JSON: %s', $ex->getMessage())); + $content = $raw_data; + } catch (PhabricatorDocumentEngineParserException $ex) { + $message = $this->newMessage( + pht( + 'Unable to parse this document as JSON: %s', + $ex->getMessage())); + $content = $raw_data; } diff --git a/src/applications/files/document/exception/PhabricatorDocumentEngineParserException.php b/src/applications/files/document/exception/PhabricatorDocumentEngineParserException.php new file mode 100644 index 0000000000..b664d942ad --- /dev/null +++ b/src/applications/files/document/exception/PhabricatorDocumentEngineParserException.php @@ -0,0 +1,4 @@ +