Commit c75726ba authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

xmllite: Support predefined xml entities.

parent 61032086
......@@ -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, &lt)) return '<';
break;
case 'g':
if (strval_eq(name, &gt)) return '>';
break;
case 'a':
if (strval_eq(name, &amp))
return '&';
else if (strval_eq(name, &apos))
return '\'';
break;
case 'q':
if (strval_eq(name, &quot)) 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)* "'" */
......
......@@ -1576,6 +1576,8 @@ static struct test_entry attributes_tests[] = {
{ "<a attr1=\"\r\n\tval\n\"/>", "attr1", " val ", S_OK },
{ "<a attr1=\"val&#32;\"/>", "attr1", "val ", S_OK },
{ "<a attr1=\"val&#x20;\"/>", "attr1", "val ", S_OK },
{ "<a attr1=\"&lt;&gt;&amp;&apos;&quot;\"/>", "attr1", "<>&\'\"", S_OK },
{ "<a attr1=\"&entname;\"/>", NULL, NULL, WC_E_UNDECLAREDENTITY },
{ "<a attr1=\"val&#xfffe;\"/>", NULL, NULL, WC_E_XMLCHARACTER },
{ "<a attr1=\"val &#a;\"/>", NULL, NULL, WC_E_DIGIT, WC_E_SEMICOLON },
{ "<a attr1=\"val &#12a;\"/>", 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 }
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment