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:
Laurence Withers 2007-01-08 12:26:55 +00:00
parent 58441639b4
commit ad6f784731
1 changed files with 23 additions and 6 deletions

View File

@ -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;