xmllite: Support predefined xml entities.
This commit is contained in:
parent
610320864b
commit
c75726ba76
@ -207,9 +207,9 @@ static const struct IUnknownVtbl xmlreaderinputvtbl;
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
WCHAR *start; /* input position where value starts */
|
|
||||||
UINT len; /* length in WCHARs, altered after ReadValueChunk */
|
|
||||||
WCHAR *str; /* allocated null-terminated string */
|
WCHAR *str; /* allocated null-terminated string */
|
||||||
|
UINT len; /* length in WCHARs, altered after ReadValueChunk */
|
||||||
|
WCHAR *start; /* input position where value starts */
|
||||||
} strval;
|
} strval;
|
||||||
|
|
||||||
static WCHAR emptyW[] = {0};
|
static WCHAR emptyW[] = {0};
|
||||||
@ -1788,11 +1788,50 @@ static void reader_normalize_space(xmlreader *reader, WCHAR *ptr)
|
|||||||
*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]+ ';'
|
/* [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
|
||||||
[67] Reference ::= EntityRef | CharRef
|
[67] Reference ::= EntityRef | CharRef
|
||||||
[68] EntityRef ::= '&' Name ';' */
|
[68] EntityRef ::= '&' Name ';' */
|
||||||
static HRESULT reader_parse_reference(xmlreader *reader)
|
static HRESULT reader_parse_reference(xmlreader *reader)
|
||||||
{
|
{
|
||||||
|
encoded_buffer *buffer = &reader->input->buffer->utf16;
|
||||||
WCHAR *start = reader_get_cur(reader), *ptr;
|
WCHAR *start = reader_get_cur(reader), *ptr;
|
||||||
WCHAR ch = 0;
|
WCHAR ch = 0;
|
||||||
int len;
|
int len;
|
||||||
@ -1803,8 +1842,6 @@ static HRESULT reader_parse_reference(xmlreader *reader)
|
|||||||
|
|
||||||
if (*ptr == '#')
|
if (*ptr == '#')
|
||||||
{
|
{
|
||||||
encoded_buffer *buffer = &reader->input->buffer->utf16;
|
|
||||||
|
|
||||||
reader_skipn(reader, 1);
|
reader_skipn(reader, 1);
|
||||||
ptr = reader_get_cur(reader);
|
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);
|
len = buffer->written - ((char*)ptr - buffer->data) - sizeof(WCHAR);
|
||||||
memmove(start+1, ptr+1, len);
|
memmove(start+1, ptr+1, len);
|
||||||
buffer->cur = (char*)start;
|
buffer->cur = (char*)(start+1);
|
||||||
|
|
||||||
*start = ch;
|
*start = ch;
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
else
|
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)* "'" */
|
/* [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=\"\r\n\tval\n\"/>", "attr1", " val ", S_OK },
|
||||||
{ "<a attr1=\"val \"/>", "attr1", "val ", S_OK },
|
{ "<a attr1=\"val \"/>", "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\"/>", 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_DIGIT, WC_E_SEMICOLON },
|
||||||
{ "<a attr1=\"val a;\"/>", NULL, NULL, 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=\"val &#xg;\"/>", NULL, NULL, WC_E_HEXDIGIT, WC_E_SEMICOLON },
|
||||||
{ "<a attr1=attrvalue/>", NULL, NULL, WC_E_QUOTE },
|
{ "<a attr1=attrvalue/>", NULL, NULL, WC_E_QUOTE },
|
||||||
{ "<a attr1=\"attr<value\"/>", NULL, NULL, WC_E_LESSTHAN },
|
{ "<a attr1=\"attr<value\"/>", NULL, NULL, WC_E_LESSTHAN },
|
||||||
|
{ "<a attr1=\"&entname\"/>", NULL, NULL, WC_E_SEMICOLON },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user