|
1 | | -/* fab937ab8b186d7d296013669c332e6dfce2f99567882cff1f8eb24223c524a7 (2.7.4+) |
| 1 | +/* 93c1caa66e2b0310459482516af05505b57c5cb7b96df777105308fc585c85d1 (2.7.5+) |
2 | 2 | __ __ _ |
3 | 3 | ___\ \/ /_ __ __ _| |_ |
4 | 4 | / _ \\ /| '_ \ / _` | __| |
@@ -590,6 +590,8 @@ static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, |
590 | 590 | static XML_Bool FASTCALL poolGrow(STRING_POOL *pool); |
591 | 591 | static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool, |
592 | 592 | const XML_Char *s); |
| 593 | +static const XML_Char *FASTCALL poolCopyStringNoFinish(STRING_POOL *pool, |
| 594 | + const XML_Char *s); |
593 | 595 | static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, |
594 | 596 | int n); |
595 | 597 | static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool, |
@@ -5086,7 +5088,7 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end, |
5086 | 5088 | } |
5087 | 5089 | /* If we get this token, we have the start of what might be a |
5088 | 5090 | normal tag, but not a declaration (i.e. it doesn't begin with |
5089 | | - "<!"). In a DTD context, that isn't legal. |
| 5091 | + "<!" or "<?"). In a DTD context, that isn't legal. |
5090 | 5092 | */ |
5091 | 5093 | else if (tok == XML_TOK_INSTANCE_START) { |
5092 | 5094 | *nextPtr = next; |
@@ -5175,6 +5177,15 @@ entityValueProcessor(XML_Parser parser, const char *s, const char *end, |
5175 | 5177 | /* found end of entity value - can store it now */ |
5176 | 5178 | return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT, NULL); |
5177 | 5179 | } |
| 5180 | + /* If we get this token, we have the start of what might be a |
| 5181 | + normal tag, but not a declaration (i.e. it doesn't begin with |
| 5182 | + "<!" or "<?"). In a DTD context, that isn't legal. |
| 5183 | + */ |
| 5184 | + else if (tok == XML_TOK_INSTANCE_START) { |
| 5185 | + *nextPtr = next; |
| 5186 | + return XML_ERROR_SYNTAX; |
| 5187 | + } |
| 5188 | + |
5178 | 5189 | start = next; |
5179 | 5190 | } |
5180 | 5191 | } |
@@ -6789,7 +6800,14 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc, |
6789 | 6800 | return XML_ERROR_NO_MEMORY; |
6790 | 6801 | } |
6791 | 6802 |
|
6792 | | - const char *next; |
| 6803 | + const char *next = entityTextPtr; |
| 6804 | + |
| 6805 | + /* Nothing to tokenize. */ |
| 6806 | + if (entityTextPtr >= entityTextEnd) { |
| 6807 | + result = XML_ERROR_NONE; |
| 6808 | + goto endEntityValue; |
| 6809 | + } |
| 6810 | + |
6793 | 6811 | for (;;) { |
6794 | 6812 | next |
6795 | 6813 | = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */ |
@@ -7439,16 +7457,24 @@ setContext(XML_Parser parser, const XML_Char *context) { |
7439 | 7457 | else { |
7440 | 7458 | if (! poolAppendChar(&parser->m_tempPool, XML_T('\0'))) |
7441 | 7459 | return XML_FALSE; |
7442 | | - prefix |
7443 | | - = (PREFIX *)lookup(parser, &dtd->prefixes, |
7444 | | - poolStart(&parser->m_tempPool), sizeof(PREFIX)); |
7445 | | - if (! prefix) |
| 7460 | + const XML_Char *const prefixName = poolCopyStringNoFinish( |
| 7461 | + &dtd->pool, poolStart(&parser->m_tempPool)); |
| 7462 | + if (! prefixName) { |
7446 | 7463 | return XML_FALSE; |
7447 | | - if (prefix->name == poolStart(&parser->m_tempPool)) { |
7448 | | - prefix->name = poolCopyString(&dtd->pool, prefix->name); |
7449 | | - if (! prefix->name) |
7450 | | - return XML_FALSE; |
7451 | 7464 | } |
| 7465 | + |
| 7466 | + prefix = (PREFIX *)lookup(parser, &dtd->prefixes, prefixName, |
| 7467 | + sizeof(PREFIX)); |
| 7468 | + |
| 7469 | + const bool prefixNameUsed = prefix && prefix->name == prefixName; |
| 7470 | + if (prefixNameUsed) |
| 7471 | + poolFinish(&dtd->pool); |
| 7472 | + else |
| 7473 | + poolDiscard(&dtd->pool); |
| 7474 | + |
| 7475 | + if (! prefix) |
| 7476 | + return XML_FALSE; |
| 7477 | + |
7452 | 7478 | poolDiscard(&parser->m_tempPool); |
7453 | 7479 | } |
7454 | 7480 | for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); |
@@ -8036,6 +8062,23 @@ poolCopyString(STRING_POOL *pool, const XML_Char *s) { |
8036 | 8062 | return s; |
8037 | 8063 | } |
8038 | 8064 |
|
| 8065 | +// A version of `poolCopyString` that does not call `poolFinish` |
| 8066 | +// and reverts any partial advancement upon failure. |
| 8067 | +static const XML_Char *FASTCALL |
| 8068 | +poolCopyStringNoFinish(STRING_POOL *pool, const XML_Char *s) { |
| 8069 | + const XML_Char *const original = s; |
| 8070 | + do { |
| 8071 | + if (! poolAppendChar(pool, *s)) { |
| 8072 | + // Revert any previously successful advancement |
| 8073 | + const ptrdiff_t advancedBy = s - original; |
| 8074 | + if (advancedBy > 0) |
| 8075 | + pool->ptr -= advancedBy; |
| 8076 | + return NULL; |
| 8077 | + } |
| 8078 | + } while (*s++); |
| 8079 | + return pool->start; |
| 8080 | +} |
| 8081 | + |
8039 | 8082 | static const XML_Char * |
8040 | 8083 | poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { |
8041 | 8084 | if (! pool->ptr && ! poolGrow(pool)) { |
|
0 commit comments