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 ]
|
StateRestartMarker2, // after second ]
|
||||||
StateOpen, // after <
|
StateOpen, // after <
|
||||||
StateOpenBang, // after <!
|
StateOpenBang, // after <!
|
||||||
StateOpenCdataMarker, // after <![
|
StateOpenBangMarker, // after <![
|
||||||
|
StateOpenCdataMarker, // after <![C
|
||||||
|
StateOpenRestartMarker, // after <![R
|
||||||
StateCDATA,
|
StateCDATA,
|
||||||
StateCDATA1, // first ]
|
StateCDATA1, // first ]
|
||||||
StateCDATA2, // second ]
|
StateCDATA2, // second ]
|
||||||
|
@ -110,7 +112,7 @@ int csxml_feedChar(struct csxml* ctx, char ch)
|
||||||
int try;
|
int try;
|
||||||
|
|
||||||
#ifdef DEBUG_STATE_MACHINE
|
#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
|
#endif
|
||||||
|
|
||||||
#define ERROR(_reason) do { \
|
#define ERROR(_reason) do { \
|
||||||
|
@ -141,8 +143,8 @@ int csxml_feedChar(struct csxml* ctx, char ch)
|
||||||
|
|
||||||
if(ch == xmlRestartMarker[ctx->restartCount]) {
|
if(ch == xmlRestartMarker[ctx->restartCount]) {
|
||||||
if(++ctx->restartCount == 11) {
|
if(++ctx->restartCount == 11) {
|
||||||
ctx->state = StateRestartMarker;
|
|
||||||
csxml_reset(ctx);
|
csxml_reset(ctx);
|
||||||
|
ctx->state = StateRestartMarker;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -343,19 +345,34 @@ int csxml_feedChar(struct csxml* ctx, char ch)
|
||||||
|
|
||||||
case StateOpenBang:
|
case StateOpenBang:
|
||||||
if(ch == '[') {
|
if(ch == '[') {
|
||||||
// restart markers handled by lower layer
|
ctx->state = StateOpenBangMarker;
|
||||||
ctx->state = StateOpenCdataMarker;
|
|
||||||
ctx->xmlCount = 3;
|
ctx->xmlCount = 3;
|
||||||
if(!ctx->elementDepth) ERROR("CDATA sections not valid at stream level.");
|
|
||||||
} else if(ch == '-') ctx->state = StateOpenComment;
|
} else if(ch == '-') ctx->state = StateOpenComment;
|
||||||
else ERROR("Invalid special tag.");
|
else ERROR("Invalid special tag.");
|
||||||
break;
|
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:
|
case StateOpenCdataMarker:
|
||||||
if(ch != xmlCdataMarker[ctx->xmlCount]) ERROR("Invalid marked section.");
|
if(ch != xmlCdataMarker[ctx->xmlCount]) ERROR("Invalid marked section.");
|
||||||
if(!xmlCdataMarker[++ctx->xmlCount]) ctx->state = StateCDATA;
|
if(!xmlCdataMarker[++ctx->xmlCount]) ctx->state = StateCDATA;
|
||||||
break;
|
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:
|
case StateOpenComment:
|
||||||
if(ch != '-') ERROR("Invalid special tag.");
|
if(ch != '-') ERROR("Invalid special tag.");
|
||||||
ctx->state = StateComment;
|
ctx->state = StateComment;
|
||||||
|
|
Loading…
Reference in New Issue