Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 8 included reviews per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe XML request body parser now releases the ARGS parsing context during destruction and malformed-document handling. Two regression cases cover malformed XML with XML-to-ARGS parsing enabled. ChangesXML parser cleanup
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
With SecParseXmlIntoArgs set to On, XML::processChunk() creates a second libxml2 push parser context, xml_data::parsing_ctx_arg, in addition to the regular parsing_ctx. That context is only released in XML::complete(), in the block that terminates the ARGS parsing. XML::complete() finishes the main context first and returns early with "XML: Failed to parse document." when the document is not well formed, before reaching the block that frees parsing_ctx_arg. ~XML() released parsing_ctx and doc but not parsing_ctx_arg, so nothing ever freed it. A remote client could therefore leak the ARGS parser context, including its body-sized input buffer, on every request carrying a malformed XML body. parsing_ctx_arg is now freed in ~XML() and, through the same small helper (XML::freeArgsParserCtx()), also freed and cleared before the early return in XML::complete() so that the memory is released as soon as the parsing is known to have failed rather than at the end of the transaction. The copy of the pointer kept in xml_data::xml_parser_state is only used from the SAX callbacks while parsing is in progress, and both changes stay inside the existing WITH_LIBXML2 guard. A regression test covering a mismatched end tag and a truncated document is added; under valgrind the unfixed code reports the context allocated in xmlCreatePushParserCtxt() as definitely lost for each request.
370210c to
030d382
Compare
|



what
xml_data::parsing_ctx_argin~XML(), following the existing pattern forparsing_ctx.parsing_ctx_argbefore the earlyreturn falseinXML::complete()when the document is not well formed.test/test-cases/regression/request-body-parser-xml-into-args.json(mismatched end tag, truncated document) withSecParseXmlIntoArgs On.why
SecParseXmlIntoArgs On,XML::processChunk()creates a second libxml2 push parser context (parsing_ctx_arg) for the ARGS extraction. It was only released in the second block ofXML::complete().complete()finishes the main context first and returns early with "XML: Failed to parse document." when the document is not well formed, before reaching that block.~XML()releasedparsing_ctxanddocbut notparsing_ctx_arg, so nothing ever freed it.Transaction::processRequestBody()).xml_data::xml_parser_stateis a non-owning alias only dereferenced from SAX callbacks while parsing is in progress, so freeing in~XML()cannot double free. Both edits are inside the existingWITH_LIBXML2guard.Evidence, unfixed tree,
libtool --mode=execute valgrind --leak-check=full ./regression_tests test-cases/regression/request-body-parser-xml-into-args.json:With the fix:
All heap blocks were freed -- no leaks are possible.make check: TOTAL 5045, PASS 5029, SKIP 16, FAIL 0.references
Summary by CodeRabbit
Bug Fixes
Tests