Module: wine Branch: master Commit: c75726ba76935553bf37facc07677152d8956f08 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c75726ba76935553bf37facc07...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Tue Aug 20 14:07:32 2013 +0400
xmllite: Support predefined xml entities.
---
dlls/xmllite/reader.c | 79 ++++++++++++++++++++++++++++++++++++++----- dlls/xmllite/tests/reader.c | 3 ++ 2 files changed, 73 insertions(+), 9 deletions(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c index efdc6ff..e193e9d 100644 --- a/dlls/xmllite/reader.c +++ b/dlls/xmllite/reader.c @@ -207,9 +207,9 @@ static const struct IUnknownVtbl xmlreaderinputvtbl; */ typedef struct { - WCHAR *start; /* input position where value starts */ - UINT len; /* length in WCHARs, altered after ReadValueChunk */ WCHAR *str; /* allocated null-terminated string */ + UINT len; /* length in WCHARs, altered after ReadValueChunk */ + WCHAR *start; /* input position where value starts */ } strval;
static WCHAR emptyW[] = {0}; @@ -1788,11 +1788,50 @@ static void reader_normalize_space(xmlreader *reader, WCHAR *ptr) *ptr = ' '; }
+static WCHAR get_predefined_entity(const strval *name) +{ + static const WCHAR entltW[] = {'l','t'}; + static const WCHAR entgtW[] = {'g','t'}; + static const WCHAR entampW[] = {'a','m','p'}; + static const WCHAR entaposW[] = {'a','p','o','s'}; + static const WCHAR entquotW[] = {'q','u','o','t'}; + + static const strval lt = { (WCHAR*)entltW, 2 }; + static const strval gt = { (WCHAR*)entgtW, 2 }; + static const strval amp = { (WCHAR*)entampW, 3 }; + static const strval apos = { (WCHAR*)entaposW, 4 }; + static const strval quot = { (WCHAR*)entquotW, 4 }; + + switch (name->str[0]) + { + case 'l': + if (strval_eq(name, <)) return '<'; + break; + case 'g': + if (strval_eq(name, >)) return '>'; + break; + case 'a': + if (strval_eq(name, &)) + return '&'; + else if (strval_eq(name, &apos)) + return '''; + break; + case 'q': + if (strval_eq(name, ")) return '"'; + break; + default: + ; + } + + return 0; +} + /* [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';' [67] Reference ::= EntityRef | CharRef [68] EntityRef ::= '&' Name ';' */ static HRESULT reader_parse_reference(xmlreader *reader) { + encoded_buffer *buffer = &reader->input->buffer->utf16; WCHAR *start = reader_get_cur(reader), *ptr; WCHAR ch = 0; int len; @@ -1803,8 +1842,6 @@ static HRESULT reader_parse_reference(xmlreader *reader)
if (*ptr == '#') { - encoded_buffer *buffer = &reader->input->buffer->utf16; - reader_skipn(reader, 1); ptr = reader_get_cur(reader);
@@ -1850,16 +1887,40 @@ static HRESULT reader_parse_reference(xmlreader *reader)
len = buffer->written - ((char*)ptr - buffer->data) - sizeof(WCHAR); memmove(start+1, ptr+1, len); - buffer->cur = (char*)start; + buffer->cur = (char*)(start+1);
*start = ch; - - return S_OK; } else - FIXME("Entity references not supported\n"); + { + strval name; + HRESULT hr;
- return E_NOTIMPL; + hr = reader_parse_name(reader, &name); + if (FAILED(hr)) return hr; + + ptr = reader_get_cur(reader); + if (*ptr != ';') return WC_E_SEMICOLON; + + /* predefined entities resolve to a single character */ + ch = get_predefined_entity(&name); + if (ch) + { + len = buffer->written - ((char*)ptr - buffer->data) - sizeof(WCHAR); + memmove(start+1, ptr+1, len); + buffer->cur = (char*)(start+1); + + *start = ch; + } + else + { + FIXME("undeclared entity %s\n", debugstr_wn(name.str, name.len)); + return WC_E_UNDECLAREDENTITY; + } + + } + + return S_OK; }
/* [10 NS] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'" */ diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c index b53c044..d7400bc 100644 --- a/dlls/xmllite/tests/reader.c +++ b/dlls/xmllite/tests/reader.c @@ -1576,6 +1576,8 @@ static struct test_entry attributes_tests[] = { { "<a attr1="\r\n\tval\n"/>", "attr1", " val ", S_OK }, { "<a attr1="val "/>", "attr1", "val ", S_OK }, { "<a attr1="val "/>", "attr1", "val ", S_OK }, + { "<a attr1="<>&'""/>", "attr1", "<>&'"", S_OK }, + { "<a attr1="&entname;"/>", NULL, NULL, WC_E_UNDECLAREDENTITY }, { "<a attr1="val"/>", NULL, NULL, WC_E_XMLCHARACTER }, { "<a attr1="val &#a;"/>", NULL, NULL, WC_E_DIGIT, WC_E_SEMICOLON }, { "<a attr1="val a;"/>", NULL, NULL, WC_E_SEMICOLON }, @@ -1583,6 +1585,7 @@ static struct test_entry attributes_tests[] = { { "<a attr1="val &#xg;"/>", NULL, NULL, WC_E_HEXDIGIT, WC_E_SEMICOLON }, { "<a attr1=attrvalue/>", NULL, NULL, WC_E_QUOTE }, { "<a attr1="attr<value"/>", NULL, NULL, WC_E_LESSTHAN }, + { "<a attr1="&entname"/>", NULL, NULL, WC_E_SEMICOLON }, { NULL } };