Repository navigation
XML body processor: surface libxml2's parse error in REQBODY_ERROR_MSG and the debug log #3678
Description
What
When the XML request body processor fails, the only diagnostic a user gets is the fixed string XML: Failed to parse document. in REQBODY_ERROR_MSG (and the matching [data "..."] of rule 200002). libxml2 knows exactly what went wrong, for example Extra content at the end of the document or Opening and ending tag mismatch: book line 1 and bookasdf, with line and column, but we discard it.
Until 3.0.15 that detail leaked to stderr by accident. #3677 silences it properly, so from now on it is lost entirely.
Proposal
After a failed xmlParseChunk() in src/request_body_processor/xml.cc, read xmlCtxtGetLastError(ctx) and, when it returns non-null, build the error string from its message, line and int2 (column) fields instead of the fixed text:
XML: Failed to parse document: Extra content at the end of the document (line 1, column 13)
Apply the same to the _arg context (Failed to parse document for ARGS.). Keep the fixed text as the fallback when xmlCtxtGetLastError() returns null or an empty message.
xmlCtxtGetLastError() is available and non-deprecated in every libxml2 release we build against (checked 2.9.13 and 2.15.4). The 2.15 headers state that errors remain accessible through it when XML_PARSE_NOERROR is set, so this works on top of #3677 with no LIBXML_VERSION conditionals and no SAX or structured-error callback.
Why
- Operators debugging rule 200002 hits today have to reproduce the request with the body captured, which several reporters on REQBODY_ERROR "Extra content at the end of the document" after 3.0.15 update #3563 could not do for PCI reasons. The libxml2 message alone often tells them whether it was a truncated body, a wrong
Content-Type, or a genuine probe. - Rule writers can match on
REQBODY_ERROR_MSGto treat, say,Document is emptydifferently from a tag mismatch. - The message is libxml2's own text, which is what the stderr line used to show, so no new information is exposed beyond what 3.0.15 and 3.0.16 already printed.
Things to decide
- Whether to trim the message to a fixed length. libxml2 messages are short, but
messagecan embed element names from the body. - Whether the new text goes only into the debug log at level 4 or also into
REQBODY_ERROR_MSG. The proposal above says both, since the variable is where rule writers can act on it. - Whether
@validateSchemaand@validateDTDshould get the same treatment. They are separate code paths (src/operators/validate_schema.cc,validate_dtd.cc) and currently use their own error callbacks; out of scope here unless someone wants it.
Test
Extend test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json (or add a sibling) with a rule that matches REQBODY_ERROR_MSG against @contains Opening and ending tag mismatch, so the message content is asserted, not just that an error occurred.
Activity