Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
71a07330
Commit
71a07330
authored
Mar 07, 2017
by
Nikolay Sivov
Committed by
Alexandre Julliard
Mar 07, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xmllite/reader: Enforce maximum element depth limit.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ce84b205
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
181 additions
and
49 deletions
+181
-49
reader.c
dlls/xmllite/reader.c
+11
-13
reader.c
dlls/xmllite/tests/reader.c
+170
-36
No files found.
dlls/xmllite/reader.c
View file @
71a07330
...
...
@@ -474,8 +474,7 @@ static void reader_clear_elements(xmlreader *reader)
static
HRESULT
reader_inc_depth
(
xmlreader
*
reader
)
{
if
(
++
reader
->
depth
>
reader
->
max_depth
)
return
SC_E_MAXELEMENTDEPTH
;
return
S_OK
;
return
(
++
reader
->
depth
>=
reader
->
max_depth
&&
reader
->
max_depth
)
?
SC_E_MAXELEMENTDEPTH
:
S_OK
;
}
static
void
reader_dec_depth
(
xmlreader
*
reader
)
...
...
@@ -2471,16 +2470,17 @@ static HRESULT reader_parse_nextnode(xmlreader *reader)
/* When moving from EndElement or empty element, pop its own namespace definitions */
switch
(
nodetype
)
{
case
XmlNodeType_Attribute
:
reader_dec_depth
(
reader
);
/* fallthrough */
case
XmlNodeType_Element
:
if
(
reader
->
is_empty_element
)
reader_pop_ns_nodes
(
reader
,
&
reader
->
empty_element
);
else
re
ader_inc_depth
(
reader
)
;
else
if
(
FAILED
(
hr
=
reader_inc_depth
(
reader
)))
re
turn
hr
;
break
;
case
XmlNodeType_EndElement
:
reader_pop_element
(
reader
);
/* fallthrough */
case
XmlNodeType_Attribute
:
reader_dec_depth
(
reader
);
break
;
default:
...
...
@@ -2735,6 +2735,9 @@ static HRESULT WINAPI xmlreader_GetProperty(IXmlReader* iface, UINT property, LO
case
XmlReaderProperty_ReadState
:
*
value
=
This
->
state
;
break
;
case
XmlReaderProperty_MaxElementDepth
:
*
value
=
This
->
max_depth
;
break
;
default:
FIXME
(
"Unimplemented property (%u)
\n
"
,
property
);
return
E_NOTIMPL
;
...
...
@@ -2772,7 +2775,7 @@ static HRESULT WINAPI xmlreader_SetProperty(IXmlReader* iface, UINT property, LO
This
->
dtdmode
=
value
;
break
;
case
XmlReaderProperty_MaxElementDepth
:
FIXME
(
"Ignoring MaxElementDepth %ld
\n
"
,
value
)
;
This
->
max_depth
=
value
;
break
;
default:
FIXME
(
"Unimplemented property (%u)
\n
"
,
property
);
...
...
@@ -2822,12 +2825,7 @@ static HRESULT reader_move_to_first_attribute(xmlreader *reader)
return
S_FALSE
;
if
(
!
reader
->
attr
)
{
HRESULT
hr
;
if
(
FAILED
(
hr
=
reader_inc_depth
(
reader
)))
return
hr
;
}
reader_inc_depth
(
reader
);
reader
->
attr
=
LIST_ENTRY
(
list_head
(
&
reader
->
attrs
),
struct
attribute
,
entry
);
reader_set_strvalue
(
reader
,
StringValue_Prefix
,
&
reader
->
attr
->
prefix
);
...
...
dlls/xmllite/tests/reader.c
View file @
71a07330
/*
* IXmlReader tests
*
* Copyright 2010, 2012-2013 Nikolay Sivov
* Copyright 2010, 2012-2013
, 2016-2017
Nikolay Sivov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -213,28 +213,26 @@ static const char *type_to_str(XmlNodeType type)
}
}
static
void
test_read_state
_
(
IXmlReader
*
reader
,
XmlReadState
expected
,
XmlReadState
exp_broken
,
BOOL
todo
,
int
line
)
static
void
test_read_state
(
IXmlReader
*
reader
,
XmlReadState
expected
,
XmlReadState
exp_broken
,
int
line
)
{
LONG_PTR
state
;
HRESULT
hr
;
BOOL
broken_state
;
LONG_PTR
state
;
state
=
-
1
;
/* invalid value */
hr
=
IXmlReader_GetProperty
(
reader
,
XmlReaderProperty_ReadState
,
&
state
);
ok_
(
__FILE__
,
line
)(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
state
=
-
1
;
/* invalid state value */
IXmlReader_GetProperty
(
reader
,
XmlReaderProperty_ReadState
,
&
state
);
if
(
exp_broken
==
-
1
)
broken_state
=
FALSE
;
else
broken_state
=
broken
(
exp_broken
==
state
);
todo_wine_if
(
todo
)
ok_
(
__FILE__
,
line
)(
state
==
expected
||
broken_state
,
"Expected (%s), got (%s)
\n
"
,
state_to_str
(
expected
),
state_to_str
(
state
));
ok_
(
__FILE__
,
line
)(
state
==
expected
||
broken_state
,
"Expected (%s), got (%s)
\n
"
,
state_to_str
(
expected
),
state_to_str
(
state
));
}
#define test_read_state(reader, exp, brk, todo) test_read_state_(reader, exp, brk, todo, __LINE__)
#define TEST_READER_STATE(reader, state) test_read_state(reader, state, -1, __LINE__)
#define TEST_READER_STATE2(reader, state, brk) test_read_state(reader, state, brk, __LINE__)
typedef
struct
_testinput
{
...
...
@@ -420,7 +418,7 @@ static void test_reader_create(void)
hr
=
CreateXmlReader
(
&
IID_IXmlReader
,
(
void
**
)
&
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
test_read_state
(
reader
,
XmlReadState_Closed
,
-
1
,
FALSE
);
TEST_READER_STATE
(
reader
,
XmlReadState_Closed
);
nodetype
=
XmlNodeType_Element
;
hr
=
IXmlReader_GetNodeType
(
reader
,
&
nodetype
);
...
...
@@ -470,7 +468,7 @@ static void test_reader_create(void)
hr
=
IXmlReader_SetInput
(
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
test_read_state
(
reader
,
XmlReadState_Initial
,
XmlReadState_Closed
,
FALSE
);
TEST_READER_STATE2
(
reader
,
XmlReadState_Initial
,
XmlReadState_Closed
);
/* test input interface selection sequence */
hr
=
testinput_createinstance
((
void
**
)
&
input
);
...
...
@@ -533,7 +531,7 @@ static void test_readerinput(void)
hr
=
IXmlReader_SetInput
(
reader
,
reader_input
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
test_read_state
(
reader
,
XmlReadState_Initial
,
-
1
,
FALSE
);
TEST_READER_STATE
(
reader
,
XmlReadState_Initial
);
nodetype
=
XmlNodeType_Element
;
hr
=
IXmlReader_GetNodeType
(
reader
,
&
nodetype
);
...
...
@@ -553,7 +551,7 @@ static void test_readerinput(void)
hr
=
IXmlReader_SetInput
(
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
test_read_state
(
reader
,
XmlReadState_Initial
,
XmlReadState_Closed
,
FALSE
);
TEST_READER_STATE2
(
reader
,
XmlReadState_Initial
,
XmlReadState_Closed
);
IXmlReader_Release
(
reader
);
...
...
@@ -611,7 +609,7 @@ static void test_readerinput(void)
ok
(
hr
==
E_NOINTERFACE
,
"Expected E_NOINTERFACE, got %08x
\n
"
,
hr
);
ok_iids
(
&
input_iids
,
setinput_readerinput
,
NULL
,
FALSE
);
test_read_state
(
reader
,
XmlReadState_Closed
,
-
1
,
FALSE
);
TEST_READER_STATE
(
reader
,
XmlReadState_Closed
);
ref
=
IUnknown_AddRef
(
input
);
ok
(
ref
==
3
,
"Expected 3, got %d
\n
"
,
ref
);
...
...
@@ -660,7 +658,8 @@ static void test_reader_state(void)
ok
(
hr
==
E_INVALIDARG
,
"Expected E_INVALIDARG, got %08x
\n
"
,
hr
);
/* attempt to read on closed reader */
test_read_state
(
reader
,
XmlReadState_Closed
,
-
1
,
FALSE
);
TEST_READER_STATE
(
reader
,
XmlReadState_Closed
);
if
(
0
)
{
/* newer versions crash here, probably because no input was set */
...
...
@@ -673,7 +672,7 @@ if (0)
hr
=
IXmlReader_SetInput
(
reader
,
(
IUnknown
*
)
stream
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
test_read_state
(
reader
,
XmlReadState_Initial
,
-
1
,
FALSE
);
TEST_READER_STATE
(
reader
,
XmlReadState_Initial
);
nodetype
=
XmlNodeType_Element
;
hr
=
IXmlReader_Read
(
reader
,
&
nodetype
);
...
...
@@ -681,7 +680,8 @@ todo_wine
ok
(
FAILED
(
hr
),
"got %08x
\n
"
,
hr
);
ok
(
nodetype
==
XmlNodeType_None
,
"Unexpected node type %d
\n
"
,
nodetype
);
test_read_state
(
reader
,
XmlReadState_Error
,
-
1
,
TRUE
);
todo_wine
TEST_READER_STATE
(
reader
,
XmlReadState_Error
);
nodetype
=
XmlNodeType_Element
;
hr
=
IXmlReader_Read
(
reader
,
&
nodetype
);
...
...
@@ -693,6 +693,22 @@ todo_wine
IXmlReader_Release
(
reader
);
}
static
void
test_reader_depth
(
IXmlReader
*
reader
,
UINT
depth
,
UINT
brk
,
int
line
)
{
BOOL
condition
;
UINT
d
=
~
0u
;
IXmlReader_GetDepth
(
reader
,
&
d
);
condition
=
d
==
depth
;
if
(
brk
!=
~
0u
)
condition
|=
broken
(
d
==
brk
);
ok_
(
__FILE__
,
line
)(
condition
,
"Unexpected nesting depth %u, expected %u
\n
"
,
d
,
depth
);
}
#define TEST_DEPTH(reader, depth) test_reader_depth(reader, depth, ~0u, __LINE__)
#define TEST_DEPTH2(reader, depth, brk) test_reader_depth(reader, depth, brk, __LINE__)
static
void
test_read_xmldeclaration
(
void
)
{
static
const
WCHAR
xmlW
[]
=
{
'x'
,
'm'
,
'l'
,
0
};
...
...
@@ -753,12 +769,9 @@ static void test_read_xmldeclaration(void)
"Expected XmlNodeType_XmlDeclaration, got %s
\n
"
,
type_to_str
(
type
));
/* new version 1.2.x and 1.3.x properly update position for <?xml ?> */
ok_pos
(
reader
,
1
,
3
,
-
1
,
55
,
TRUE
);
test_read_state
(
reader
,
XmlReadState_Interactive
,
-
1
,
FALSE
);
count
=
1
;
hr
=
IXmlReader_GetDepth
(
reader
,
&
count
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
ok
(
count
==
0
,
"Expected 1, got %d
\n
"
,
count
);
TEST_DEPTH
(
reader
,
0
);
TEST_READER_STATE
(
reader
,
XmlReadState_Interactive
);
hr
=
IXmlReader_GetValue
(
reader
,
&
val
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
...
...
@@ -768,10 +781,7 @@ static void test_read_xmldeclaration(void)
hr
=
IXmlReader_MoveToNextAttribute
(
reader
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
count
=
0
;
hr
=
IXmlReader_GetDepth
(
reader
,
&
count
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
ok
(
count
==
1
,
"Expected 1, got %d
\n
"
,
count
);
TEST_DEPTH
(
reader
,
1
);
type
=
XmlNodeType_None
;
hr
=
IXmlReader_GetNodeType
(
reader
,
&
type
);
...
...
@@ -822,10 +832,7 @@ static void test_read_xmldeclaration(void)
ok
(
hr
==
((
i
<
count
-
1
)
?
S_OK
:
S_FALSE
),
"got %08x
\n
"
,
hr
);
}
count
=
0
;
hr
=
IXmlReader_GetDepth
(
reader
,
&
count
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
ok
(
count
==
1
,
"Expected 1, got %d
\n
"
,
count
);
TEST_DEPTH
(
reader
,
1
);
hr
=
IXmlReader_MoveToElement
(
reader
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
...
...
@@ -856,7 +863,7 @@ todo_wine {
ok
(
hr
==
S_OK
,
"expected S_OK, got %08x
\n
"
,
hr
);
ok
(
type
==
XmlNodeType_XmlDeclaration
,
"expected XmlDeclaration, got %s
\n
"
,
type_to_str
(
type
));
ok_pos
(
reader
,
1
,
3
,
1
,
21
,
TRUE
);
test_read_state
(
reader
,
XmlReadState_Interactive
,
-
1
,
FALSE
);
TEST_READER_STATE
(
reader
,
XmlReadState_Interactive
);
hr
=
IXmlReader_GetAttributeCount
(
reader
,
&
count
);
ok
(
hr
==
S_OK
,
"expected S_OK, got %08x
\n
"
,
hr
);
...
...
@@ -898,7 +905,7 @@ todo_wine {
ok
(
hr
==
S_OK
,
"expected S_OK, got %08x
\n
"
,
hr
);
ok
(
type
==
XmlNodeType_Element
,
"expected Element, got %s
\n
"
,
type_to_str
(
type
));
ok_pos
(
reader
,
1
,
23
,
1
,
40
,
TRUE
);
test_read_state
(
reader
,
XmlReadState_Interactive
,
-
1
,
FALSE
);
TEST_READER_STATE
(
reader
,
XmlReadState_Interactive
);
hr
=
IXmlReader_GetAttributeCount
(
reader
,
&
count
);
ok
(
hr
==
S_OK
,
"expected S_OK, got %08x
\n
"
,
hr
);
...
...
@@ -921,7 +928,8 @@ todo_wine
ok
(
hr
==
WC_E_SYNTAX
||
hr
==
WC_E_XMLCHARACTER
/* XP */
,
"expected WC_E_SYNTAX, got %08x
\n
"
,
hr
);
ok
(
type
==
XmlNodeType_None
,
"expected XmlNodeType_None, got %s
\n
"
,
type_to_str
(
type
));
ok_pos
(
reader
,
1
,
41
,
-
1
,
-
1
,
TRUE
);
test_read_state
(
reader
,
XmlReadState_Error
,
-
1
,
TRUE
);
todo_wine
TEST_READER_STATE
(
reader
,
XmlReadState_Error
);
IStream_Release
(
stream
);
IXmlReader_Release
(
reader
);
...
...
@@ -1953,17 +1961,28 @@ static void test_read_attribute(void)
static
void
test_reader_properties
(
void
)
{
IXmlReader
*
reader
;
LONG_PTR
value
;
HRESULT
hr
;
hr
=
CreateXmlReader
(
&
IID_IXmlReader
,
(
void
**
)
&
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"S_OK, got %08x
\n
"
,
hr
);
value
=
0
;
hr
=
IXmlReader_GetProperty
(
reader
,
XmlReaderProperty_MaxElementDepth
,
&
value
);
ok
(
hr
==
S_OK
,
"GetProperty failed: %08x
\n
"
,
hr
);
ok
(
value
==
256
,
"Unexpected default max depth value %ld
\n
"
,
value
);
hr
=
IXmlReader_SetProperty
(
reader
,
XmlReaderProperty_MultiLanguage
,
0
);
ok
(
hr
==
S_OK
,
"SetProperty failed: %08x
\n
"
,
hr
);
hr
=
IXmlReader_SetProperty
(
reader
,
XmlReaderProperty_MaxElementDepth
,
0
);
ok
(
hr
==
S_OK
,
"SetProperty failed: %08x
\n
"
,
hr
);
value
=
256
;
hr
=
IXmlReader_GetProperty
(
reader
,
XmlReaderProperty_MaxElementDepth
,
&
value
);
ok
(
hr
==
S_OK
,
"GetProperty failed: %08x
\n
"
,
hr
);
ok
(
value
==
0
,
"Unexpected max depth value %ld
\n
"
,
value
);
IXmlReader_Release
(
reader
);
}
...
...
@@ -2269,6 +2288,120 @@ static void test_endoffile(void)
IXmlReader_Release
(
reader
);
}
static
void
test_max_element_depth
(
void
)
{
static
const
char
*
xml
=
"<a>"
"<b attrb=
\"
_b
\"
>"
"<c>"
"<d></d>"
"</c>"
"</b>"
"</a>"
;
unsigned
int
count
;
IXmlReader
*
reader
;
IStream
*
stream
;
HRESULT
hr
;
hr
=
CreateXmlReader
(
&
IID_IXmlReader
,
(
void
**
)
&
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"S_OK, got %08x
\n
"
,
hr
);
stream
=
create_stream_on_data
(
xml
,
strlen
(
xml
));
hr
=
IXmlReader_SetInput
(
reader
,
(
IUnknown
*
)
stream
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
IXmlReader_SetProperty
(
reader
,
XmlReaderProperty_MaxElementDepth
,
2
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
TEST_DEPTH
(
reader
,
0
);
hr
=
IXmlReader_Read
(
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
TEST_DEPTH
(
reader
,
0
);
hr
=
IXmlReader_Read
(
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
TEST_DEPTH
(
reader
,
1
);
TEST_READER_STATE
(
reader
,
XmlReadState_Interactive
);
hr
=
IXmlReader_Read
(
reader
,
NULL
);
ok
(
hr
==
SC_E_MAXELEMENTDEPTH
,
"got %08x
\n
"
,
hr
);
todo_wine
{
TEST_DEPTH2
(
reader
,
0
,
2
);
TEST_READER_STATE
(
reader
,
XmlReadState_Error
);
}
hr
=
IXmlReader_SetProperty
(
reader
,
XmlReaderProperty_MaxElementDepth
,
10
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
IXmlReader_Read
(
reader
,
NULL
);
todo_wine
{
ok
(
hr
==
SC_E_MAXELEMENTDEPTH
,
"got %08x
\n
"
,
hr
);
TEST_DEPTH2
(
reader
,
0
,
2
);
TEST_READER_STATE
(
reader
,
XmlReadState_Error
);
}
IStream_Release
(
stream
);
/* test if stepping into attributes enforces depth limit too */
stream
=
create_stream_on_data
(
xml
,
strlen
(
xml
));
hr
=
IXmlReader_SetInput
(
reader
,
(
IUnknown
*
)
stream
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
IXmlReader_SetProperty
(
reader
,
XmlReaderProperty_MaxElementDepth
,
2
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
TEST_DEPTH
(
reader
,
0
);
hr
=
IXmlReader_Read
(
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
TEST_DEPTH
(
reader
,
0
);
hr
=
IXmlReader_Read
(
reader
,
NULL
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
TEST_DEPTH
(
reader
,
1
);
hr
=
IXmlReader_MoveToFirstAttribute
(
reader
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
TEST_DEPTH
(
reader
,
2
);
TEST_READER_STATE
(
reader
,
XmlReadState_Interactive
);
hr
=
IXmlReader_Read
(
reader
,
NULL
);
ok
(
hr
==
SC_E_MAXELEMENTDEPTH
,
"got %08x
\n
"
,
hr
);
todo_wine
{
TEST_DEPTH2
(
reader
,
0
,
2
);
TEST_READER_STATE
(
reader
,
XmlReadState_Error
);
}
IStream_Release
(
stream
);
/* set max depth to 0, this disables depth limit */
stream
=
create_stream_on_data
(
xml
,
strlen
(
xml
));
hr
=
IXmlReader_SetInput
(
reader
,
(
IUnknown
*
)
stream
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
hr
=
IXmlReader_SetProperty
(
reader
,
XmlReaderProperty_MaxElementDepth
,
0
);
ok
(
hr
==
S_OK
,
"got %08x
\n
"
,
hr
);
count
=
0
;
while
(
IXmlReader_Read
(
reader
,
NULL
)
==
S_OK
)
count
++
;
ok
(
count
==
8
,
"Unexpected node number %u
\n
"
,
count
);
TEST_READER_STATE
(
reader
,
XmlReadState_EndOfFile
);
IStream_Release
(
stream
);
IXmlReader_Release
(
reader
);
}
START_TEST
(
reader
)
{
test_reader_create
();
...
...
@@ -2293,4 +2426,5 @@ START_TEST(reader)
test_read_charref
();
test_encoding_detection
();
test_endoffile
();
test_max_element_depth
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment