Fix handling of restart markers. csxml_reset() was clearing the state after encountering a restart
marker, leaving us in stream level after <![RESTART[, which meant that the closing bit of the marker was interpreted as stream-level content. Also, the state machine now handles restart markers at high level as well as low level; this simply means that a (false) error is not issued in the case of perfectly well-formed Streamed XML containing restart markers.
This commit is contained in:
parent
58441639b4
commit
ad6f784731
|
@ -23,7 +23,9 @@ enum csxml_State {
|
|||
StateRestartMarker2, // after second ]
|
||||
StateOpen, // after <
|
||||
StateOpenBang, // after <!
|
||||
StateOpenCdataMarker, // after <![
|
||||
StateOpenBangMarker, // after <![
|
||||
StateOpenCdataMarker, // after <![C
|
||||
StateOpenRestartMarker, // after <![R
|
||||
StateCDATA,
|
||||
StateCDATA1, // first ]
|
||||
StateCDATA2, // second ]
|
||||
|
@ -110,7 +112,7 @@ int csxml_feedChar(struct csxml* ctx, char ch)
|
|||
int try;
|
||||
|
||||
#ifdef DEBUG_STATE_MACHINE
|
||||
printf("%p: Character '%c' (%02X), state %d, buffer %s\n", ctx, ch, ch, ctx->state, ctx->buffer.data);
|
||||
printf("%p: Character '%c' (%02X), state %d, buffer `%s', restartCount %d\n", ctx, ch, ch, ctx->state, ctx->buffer.data, ctx->restartCount);
|
||||
#endif
|
||||
|
||||
#define ERROR(_reason) do { \
|
||||
|
@ -141,8 +143,8 @@ int csxml_feedChar(struct csxml* ctx, char ch)
|
|||
|
||||
if(ch == xmlRestartMarker[ctx->restartCount]) {
|
||||
if(++ctx->restartCount == 11) {
|
||||
ctx->state = StateRestartMarker;
|
||||
csxml_reset(ctx);
|
||||
ctx->state = StateRestartMarker;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
|
@ -343,19 +345,34 @@ int csxml_feedChar(struct csxml* ctx, char ch)
|
|||
|
||||
case StateOpenBang:
|
||||
if(ch == '[') {
|
||||
// restart markers handled by lower layer
|
||||
ctx->state = StateOpenCdataMarker;
|
||||
ctx->state = StateOpenBangMarker;
|
||||
ctx->xmlCount = 3;
|
||||
if(!ctx->elementDepth) ERROR("CDATA sections not valid at stream level.");
|
||||
} else if(ch == '-') ctx->state = StateOpenComment;
|
||||
else ERROR("Invalid special tag.");
|
||||
break;
|
||||
|
||||
case StateOpenBangMarker:
|
||||
if(ch == xmlCdataMarker[ctx->xmlCount]) {
|
||||
ctx->state = StateOpenCdataMarker;
|
||||
if(!ctx->elementDepth) ERROR("CDATA sections not valid at stream level.");
|
||||
} else if(ch == xmlRestartMarker[ctx->xmlCount]) {
|
||||
ctx->state = StateOpenRestartMarker;
|
||||
} else {
|
||||
ERROR("Invalid marked section.");
|
||||
}
|
||||
++(ctx->xmlCount);
|
||||
break;
|
||||
|
||||
case StateOpenCdataMarker:
|
||||
if(ch != xmlCdataMarker[ctx->xmlCount]) ERROR("Invalid marked section.");
|
||||
if(!xmlCdataMarker[++ctx->xmlCount]) ctx->state = StateCDATA;
|
||||
break;
|
||||
|
||||
case StateOpenRestartMarker:
|
||||
if(ch != xmlRestartMarker[ctx->xmlCount++]) ERROR("Invalid marked section.");
|
||||
/* Restart markers handled by lower layer -- if(!xmlRestartMarker[++ctx->xmlCount]) { } */
|
||||
break;
|
||||
|
||||
case StateOpenComment:
|
||||
if(ch != '-') ERROR("Invalid special tag.");
|
||||
ctx->state = StateComment;
|
||||
|
|
Loading…
Reference in New Issue