@@ -254,15 +254,32 @@ struct JHandler : public BaseReaderHandler<UTF8<>, JHandler> {
254254// As some parsers don't support text length, they only support null
255255// terminated strings, so we have to convert the last trailer to '\0',
256256// while making the parser to treat it as the trailer.
257- inline void fix_trail (char * text, size_t size, char trailer) {
258- auto i = estring_view (text, size).rfind (trailer);
259- if (i != estring_view::npos) text[i] = ' \0 ' ;
257+ static bool fix_trail (estring_view text, char header, char trailer) {
258+ auto i = text.rfind (trailer);
259+ if (i == estring_view::npos)
260+ LOG_ERROR_RETURN (EINVAL , false , " no trailer found" );
261+ for (char c: text.substr (i+1 ))
262+ if (!isspace (c))
263+ LOG_ERROR_RETURN (EINVAL , false , " illegal character after trailer" );
264+ size_t k = 0 ;
265+ for (char c: text.substr (0 , i+1 )) {
266+ if (!c)
267+ LOG_ERROR_RETURN (EINVAL , false , " unexpected '\\ 0'" );
268+ if (c == header) ++k;
269+ else if (c == trailer)
270+ if (k-- == 0 ) goto failed;
271+ }
272+ if (k != 0 ) failed:
273+ LOG_ERROR_RETURN (EINVAL , false , " unbalanced header/trailer" );
274+ auto c = &text[i];
275+ *(char *)c = ' \0 ' ;
276+ return true ;
260277}
261278
262279static NodeImpl* parse_json (char * text, size_t size, int flags) {
263280 const auto kFlags = kParseNumbersAsStringsFlag | kParseBoolsAsStringFlag |
264281 kParseInsituFlag | kParseCommentsFlag | kParseTrailingCommasFlag ;
265- fix_trail (text, size, ' }' );
282+ if (! fix_trail ({ text, size} , ' { ' , ' }' )) return nullptr ;
266283 JHandler h (text, flags & DOC_FREE_TEXT_ON_DESTRUCTION );
267284 using Encoding = UTF8 <>;
268285 GenericInsituStringStream<Encoding> s (text);
@@ -311,7 +328,7 @@ class XMLNode : public DocNode<XMLNode> {
311328};
312329
313330static NodeImpl* parse_xml (char * text, size_t size, int flags) {
314- fix_trail (text, size, ' >' );
331+ if (! fix_trail ({ text, size} , ' < ' , ' >' )) return nullptr ;
315332 xml_document<char > doc;
316333 doc.parse <0 >(text);
317334 auto root = make_unique<XMLNode>(text, flags & DOC_FREE_TEXT_ON_DESTRUCTION );
0 commit comments