diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -3209,6 +3209,7 @@ '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 @@ '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 --- a/src/applications/files/document/PhabricatorJSONDocumentEngine.php +++ b/src/applications/files/document/PhabricatorJSONDocumentEngine.php @@ -31,6 +31,17 @@ 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 @@ '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 --- /dev/null +++ b/src/applications/files/document/exception/PhabricatorDocumentEngineParserException.php @@ -0,0 +1,4 @@ +