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
a86e2a4a
Commit
a86e2a4a
authored
Sep 11, 2018
by
Nikolay Sivov
Committed by
Alexandre Julliard
Sep 11, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xmllite/writer: Improve namespaces handling in WriteStartElement().
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
8eb054f3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
112 additions
and
92 deletions
+112
-92
writer.c
dlls/xmllite/tests/writer.c
+78
-78
writer.c
dlls/xmllite/writer.c
+34
-14
No files found.
dlls/xmllite/tests/writer.c
View file @
a86e2a4a
...
...
@@ -841,6 +841,46 @@ static void test_bom(void)
IXmlWriter_Release
(
writer
);
}
static
HRESULT
write_start_element
(
IXmlWriter
*
writer
,
const
char
*
prefix
,
const
char
*
local
,
const
char
*
uri
)
{
WCHAR
*
prefixW
,
*
localW
,
*
uriW
;
HRESULT
hr
;
prefixW
=
strdupAtoW
(
prefix
);
localW
=
strdupAtoW
(
local
);
uriW
=
strdupAtoW
(
uri
);
hr
=
IXmlWriter_WriteStartElement
(
writer
,
prefixW
,
localW
,
uriW
);
heap_free
(
prefixW
);
heap_free
(
localW
);
heap_free
(
uriW
);
return
hr
;
}
static
HRESULT
write_element_string
(
IXmlWriter
*
writer
,
const
char
*
prefix
,
const
char
*
local
,
const
char
*
uri
,
const
char
*
value
)
{
WCHAR
*
prefixW
,
*
localW
,
*
uriW
,
*
valueW
;
HRESULT
hr
;
prefixW
=
strdupAtoW
(
prefix
);
localW
=
strdupAtoW
(
local
);
uriW
=
strdupAtoW
(
uri
);
valueW
=
strdupAtoW
(
value
);
hr
=
IXmlWriter_WriteElementString
(
writer
,
prefixW
,
localW
,
uriW
,
valueW
);
heap_free
(
prefixW
);
heap_free
(
localW
);
heap_free
(
uriW
);
heap_free
(
valueW
);
return
hr
;
}
static
void
test_WriteStartElement
(
void
)
{
static
const
struct
...
...
@@ -856,24 +896,22 @@ static void test_WriteStartElement(void)
}
start_element_tests
[]
=
{
{
"prefix"
,
"local"
,
"uri"
,
"<prefix:local xmlns:prefix=
\"
uri
\"
/>"
,
"<prefix:local"
,
S_OK
,
1
},
{
NULL
,
"local"
,
"uri"
,
"<local xmlns=
\"
uri
\"
/>"
,
"<local"
,
S_OK
,
1
},
{
""
,
"local"
,
"uri"
,
"<local xmlns=
\"
uri
\"
/>"
,
"<local"
,
S_OK
,
1
},
{
""
,
"local"
,
"uri"
,
"<local xmlns=
\"
uri
\"
/>"
,
"<local"
,
S_OK
,
1
},
{
"prefix"
,
"local"
,
"uri"
,
"<prefix:local xmlns:prefix=
\"
uri
\"
/>"
,
"<prefix:local"
},
{
NULL
,
"local"
,
"uri"
,
"<local xmlns=
\"
uri
\"
/>"
,
"<local"
},
{
""
,
"local"
,
"uri"
,
"<local xmlns=
\"
uri
\"
/>"
,
"<local"
},
{
""
,
"local"
,
"uri"
,
"<local xmlns=
\"
uri
\"
/>"
,
"<local"
},
{
"prefix"
,
NULL
,
NULL
,
NULL
,
NULL
,
E_INVALIDARG
},
{
NULL
,
NULL
,
"uri"
,
NULL
,
NULL
,
E_INVALIDARG
},
{
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
E_INVALIDARG
},
{
NULL
,
"prefix:local"
,
"uri"
,
NULL
,
NULL
,
WC_E_NAMECHARACTER
,
1
,
1
},
{
"pre:fix"
,
"local"
,
"uri"
,
NULL
,
NULL
,
WC_E_NAMECHARACTER
,
1
,
1
},
{
NULL
,
":local"
,
"uri"
,
NULL
,
NULL
,
WC_E_NAMECHARACTER
,
1
,
1
},
{
":"
,
"local"
,
"uri"
,
NULL
,
NULL
,
WC_E_NAMECHARACTER
,
1
,
1
},
{
NULL
,
"prefix:local"
,
"uri"
,
NULL
,
NULL
,
WC_E_NAMECHARACTER
},
{
"pre:fix"
,
"local"
,
"uri"
,
NULL
,
NULL
,
WC_E_NAMECHARACTER
},
{
NULL
,
":local"
,
"uri"
,
NULL
,
NULL
,
WC_E_NAMECHARACTER
},
{
":"
,
"local"
,
"uri"
,
NULL
,
NULL
,
WC_E_NAMECHARACTER
},
{
NULL
,
"local"
,
"http://www.w3.org/2000/xmlns/"
,
NULL
,
NULL
,
WR_E_XMLNSPREFIXDECLARATION
},
{
"prefix"
,
"local"
,
"http://www.w3.org/2000/xmlns/"
,
NULL
,
NULL
,
WR_E_XMLNSURIDECLARATION
},
};
static
const
WCHAR
valueW
[]
=
{
'v'
,
'a'
,
'l'
,
'u'
,
'e'
,
0
};
static
const
WCHAR
aW
[]
=
{
'a'
,
0
};
static
const
WCHAR
bW
[]
=
{
'b'
,
0
};
IXmlWriter
*
writer
;
IStream
*
stream
;
unsigned
int
i
;
...
...
@@ -882,12 +920,12 @@ static void test_WriteStartElement(void)
hr
=
CreateXmlWriter
(
&
IID_IXmlWriter
,
(
void
**
)
&
writer
,
NULL
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
hr
=
IXmlWriter_WriteStartElement
(
writer
,
NULL
,
aW
,
NULL
);
hr
=
write_start_element
(
writer
,
NULL
,
"a"
,
NULL
);
ok
(
hr
==
E_UNEXPECTED
,
"got 0x%08x
\n
"
,
hr
);
stream
=
writer_set_output
(
writer
);
hr
=
IXmlWriter_WriteStartElement
(
writer
,
NULL
,
aW
,
NULL
);
hr
=
write_start_element
(
writer
,
NULL
,
"a"
,
NULL
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IXmlWriter_WriteStartDocument
(
writer
,
XmlStandalone_Yes
);
...
...
@@ -914,33 +952,45 @@ static void test_WriteStartElement(void)
hr
=
CreateXmlWriter
(
&
IID_IXmlWriter
,
(
void
**
)
&
writer
,
NULL
);
ok
(
hr
==
S_OK
,
"Expected S_OK, got %08x
\n
"
,
hr
);
hr
=
IXmlWriter_WriteElementString
(
writer
,
NULL
,
bW
,
NULL
,
valueW
);
hr
=
write_element_string
(
writer
,
NULL
,
"b"
,
NULL
,
"value"
);
ok
(
hr
==
E_UNEXPECTED
,
"got 0x%08x
\n
"
,
hr
);
stream
=
writer_set_output
(
writer
);
hr
=
IXmlWriter_WriteStartElement
(
writer
,
NULL
,
aW
,
NULL
);
ok
(
hr
==
S_OK
,
"
got 0x%08x
\n
"
,
hr
);
hr
=
write_start_element
(
writer
,
"prefix"
,
"a"
,
"uri"
);
ok
(
hr
==
S_OK
,
"
Failed to start element, hr %#x.
\n
"
,
hr
);
hr
=
IXmlWriter_WriteElementString
(
writer
,
NULL
,
bW
,
NULL
,
valueW
);
ok
(
hr
==
S_OK
,
"
got 0x%08x
\n
"
,
hr
);
hr
=
write_element_string
(
writer
,
NULL
,
"b"
,
NULL
,
"value"
);
ok
(
hr
==
S_OK
,
"
Failed to write element string, hr %#x.
\n
"
,
hr
);
hr
=
IXmlWriter_WriteElementString
(
writer
,
NULL
,
bW
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
write_element_string
(
writer
,
NULL
,
"c"
,
NULL
,
NULL
);
ok
(
hr
==
S_OK
,
"Failed to write element string, hr %#x.
\n
"
,
hr
);
hr
=
write_start_element
(
writer
,
NULL
,
"d"
,
"uri"
);
ok
(
hr
==
S_OK
,
"Failed to start element, hr %#x.
\n
"
,
hr
);
hr
=
write_start_element
(
writer
,
""
,
"e"
,
"uri"
);
ok
(
hr
==
S_OK
,
"Failed to start element, hr %#x.
\n
"
,
hr
);
hr
=
write_start_element
(
writer
,
"prefix2"
,
"f"
,
"uri"
);
ok
(
hr
==
S_OK
,
"Failed to start element, hr %#x.
\n
"
,
hr
);
hr
=
IXmlWriter_Flush
(
writer
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
CHECK_OUTPUT
(
stream
,
"<a><b>value</b><b />"
);
"<prefix:a xmlns:prefix=
\"
uri
\"
>"
"<b>value</b>"
"<c />"
"<prefix:d>"
"<e xmlns=
\"
uri
\"
>"
"<prefix2:f"
);
IStream_Release
(
stream
);
/* WriteStartElement */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
start_element_tests
);
++
i
)
{
WCHAR
*
prefixW
,
*
localW
,
*
uriW
;
stream
=
writer_set_output
(
writer
);
writer_set_property
(
writer
,
XmlWriterProperty_OmitXmlDeclaration
);
...
...
@@ -948,12 +998,8 @@ static void test_WriteStartElement(void)
hr
=
IXmlWriter_WriteStartDocument
(
writer
,
XmlStandalone_Omit
);
ok
(
hr
==
S_OK
,
"Failed to start document, hr %#x.
\n
"
,
hr
);
prefixW
=
strdupAtoW
(
start_element_tests
[
i
].
prefix
);
localW
=
strdupAtoW
(
start_element_tests
[
i
].
local
);
uriW
=
strdupAtoW
(
start_element_tests
[
i
].
uri
);
hr
=
IXmlWriter_WriteStartElement
(
writer
,
prefixW
,
localW
,
uriW
);
todo_wine_if
(
i
>=
11
)
hr
=
write_start_element
(
writer
,
start_element_tests
[
i
].
prefix
,
start_element_tests
[
i
].
local
,
start_element_tests
[
i
].
uri
);
ok
(
hr
==
start_element_tests
[
i
].
hr
,
"%u: unexpected hr %#x.
\n
"
,
i
,
hr
);
if
(
SUCCEEDED
(
start_element_tests
[
i
].
hr
))
...
...
@@ -972,56 +1018,12 @@ static void test_WriteStartElement(void)
check_output
(
stream
,
start_element_tests
[
i
].
output
,
start_element_tests
[
i
].
todo
,
__LINE__
);
}
heap_free
(
prefixW
);
heap_free
(
localW
);
heap_free
(
uriW
);
IStream_Release
(
stream
);
}
IXmlWriter_Release
(
writer
);
}
static
HRESULT
write_element_string
(
IXmlWriter
*
writer
,
const
char
*
prefix
,
const
char
*
local
,
const
char
*
uri
,
const
char
*
value
)
{
WCHAR
*
prefixW
,
*
localW
,
*
uriW
,
*
valueW
;
HRESULT
hr
;
prefixW
=
strdupAtoW
(
prefix
);
localW
=
strdupAtoW
(
local
);
uriW
=
strdupAtoW
(
uri
);
valueW
=
strdupAtoW
(
value
);
hr
=
IXmlWriter_WriteElementString
(
writer
,
prefixW
,
localW
,
uriW
,
valueW
);
heap_free
(
prefixW
);
heap_free
(
localW
);
heap_free
(
uriW
);
heap_free
(
valueW
);
return
hr
;
}
static
HRESULT
write_start_element
(
IXmlWriter
*
writer
,
const
char
*
prefix
,
const
char
*
local
,
const
char
*
uri
)
{
WCHAR
*
prefixW
,
*
localW
,
*
uriW
;
HRESULT
hr
;
prefixW
=
strdupAtoW
(
prefix
);
localW
=
strdupAtoW
(
local
);
uriW
=
strdupAtoW
(
uri
);
hr
=
IXmlWriter_WriteStartElement
(
writer
,
prefixW
,
localW
,
uriW
);
heap_free
(
prefixW
);
heap_free
(
localW
);
heap_free
(
uriW
);
return
hr
;
}
static
void
test_WriteElementString
(
void
)
{
static
const
struct
...
...
@@ -1164,10 +1166,8 @@ static void test_WriteElementString(void)
IXmlWriter_Release
(
writer
);
}
static
void
test_
writeende
lement
(
void
)
static
void
test_
WriteEndE
lement
(
void
)
{
static
const
WCHAR
aW
[]
=
{
'a'
,
0
};
static
const
WCHAR
bW
[]
=
{
'b'
,
0
};
IXmlWriter
*
writer
;
IStream
*
stream
;
HRESULT
hr
;
...
...
@@ -1177,10 +1177,10 @@ static void test_writeendelement(void)
stream
=
writer_set_output
(
writer
);
hr
=
IXmlWriter_WriteStartElement
(
writer
,
NULL
,
aW
,
NULL
);
hr
=
write_start_element
(
writer
,
NULL
,
"a"
,
NULL
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IXmlWriter_WriteStartElement
(
writer
,
NULL
,
bW
,
NULL
);
hr
=
write_start_element
(
writer
,
NULL
,
"b"
,
NULL
);
ok
(
hr
==
S_OK
,
"got 0x%08x
\n
"
,
hr
);
hr
=
IXmlWriter_WriteEndElement
(
writer
);
...
...
@@ -1892,7 +1892,7 @@ START_TEST(writer)
test_writestartdocument
();
test_WriteStartElement
();
test_WriteElementString
();
test_
writeende
lement
();
test_
WriteEndE
lement
();
test_flush
();
test_omitxmldeclaration
();
test_bom
();
...
...
dlls/xmllite/writer.c
View file @
a86e2a4a
...
...
@@ -497,15 +497,9 @@ static HRESULT write_xmldecl(xmlwriter *writer, XmlStandalone standalone)
return
S_OK
;
}
static
HRESULT
writer_close_starttag
(
xmlwriter
*
writer
)
static
void
writer_output_ns
(
xmlwriter
*
writer
,
struct
element
*
element
)
{
struct
element
*
element
;
struct
ns
*
ns
;
HRESULT
hr
;
if
(
!
writer
->
starttagopen
)
return
S_OK
;
element
=
LIST_ENTRY
(
list_head
(
&
writer
->
elements
),
struct
element
,
entry
);
LIST_FOR_EACH_ENTRY
(
ns
,
&
element
->
ns
,
struct
ns
,
entry
)
{
...
...
@@ -513,7 +507,15 @@ static HRESULT writer_close_starttag(xmlwriter *writer)
write_output_buffer
(
writer
->
output
,
eqW
,
ARRAY_SIZE
(
eqW
));
write_output_buffer_quoted
(
writer
->
output
,
ns
->
uri
,
-
1
);
}
}
static
HRESULT
writer_close_starttag
(
xmlwriter
*
writer
)
{
HRESULT
hr
;
if
(
!
writer
->
starttagopen
)
return
S_OK
;
writer_output_ns
(
writer
,
LIST_ENTRY
(
list_head
(
&
writer
->
elements
),
struct
element
,
entry
));
hr
=
write_output_buffer
(
writer
->
output
,
gtW
,
ARRAY_SIZE
(
gtW
));
writer
->
starttagopen
=
FALSE
;
return
hr
;
...
...
@@ -967,6 +969,8 @@ static struct ns *writer_find_ns(xmlwriter *writer, const WCHAR *prefix, const W
}
else
if
(
!
strcmpW
(
uri
,
ns
->
uri
))
{
if
(
prefix
&&
!*
prefix
)
return
NULL
;
if
(
!
prefix
||
!
strcmpW
(
prefix
,
ns
->
prefix
))
return
ns
;
}
...
...
@@ -1114,11 +1118,13 @@ static HRESULT WINAPI xmlwriter_WriteEndElement(IXmlWriter *iface)
if
(
This
->
starttagopen
)
{
writer_output_ns
(
This
,
element
);
write_output_buffer
(
This
->
output
,
closetagW
,
ARRAY_SIZE
(
closetagW
));
This
->
starttagopen
=
FALSE
;
}
else
{
/* write full end tag */
else
{
/* Write full end tag. */
write_node_indent
(
This
);
write_output_buffer
(
This
->
output
,
closeelementW
,
ARRAY_SIZE
(
closeelementW
));
write_output_buffer
(
This
->
output
,
element
->
qname
,
element
->
len
);
...
...
@@ -1402,6 +1408,7 @@ static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR pre
xmlwriter
*
This
=
impl_from_IXmlWriter
(
iface
);
int
prefix_len
,
local_len
;
struct
element
*
element
;
struct
ns
*
ns
;
HRESULT
hr
;
TRACE
(
"(%p)->(%s %s %s)
\n
"
,
This
,
wine_dbgstr_w
(
prefix
),
wine_dbgstr_w
(
local_name
),
wine_dbgstr_w
(
uri
));
...
...
@@ -1417,6 +1424,9 @@ static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR pre
return
MX_E_ENCODING
;
case
XmlWriterState_DocClosed
:
return
WR_E_INVALIDACTION
;
case
XmlWriterState_ElemStarted
:
writer_close_starttag
(
This
);
break
;
default:
;
}
...
...
@@ -1428,9 +1438,16 @@ static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR pre
if
(
FAILED
(
hr
=
is_valid_ncname
(
local_name
,
&
local_len
)))
return
hr
;
/* close pending element */
if
(
This
->
starttagopen
)
write_output_buffer
(
This
->
output
,
gtW
,
ARRAY_SIZE
(
gtW
));
if
(
uri
&&
!
strcmpW
(
uri
,
xmlnsuriW
))
{
if
(
!
prefix
)
return
WR_E_XMLNSPREFIXDECLARATION
;
if
(
!
is_empty_string
(
prefix
))
return
WR_E_XMLNSURIDECLARATION
;
}
ns
=
writer_find_ns
(
This
,
prefix
,
uri
);
element
=
alloc_element
(
This
,
prefix
,
local_name
);
if
(
!
element
)
...
...
@@ -1444,11 +1461,14 @@ static HRESULT WINAPI xmlwriter_WriteStartElement(IXmlWriter *iface, LPCWSTR pre
writer_push_element
(
This
,
element
);
if
(
prefix_len
&&
uri
)
if
(
!
ns
&&
uri
)
writer_push_ns
(
This
,
prefix
,
prefix_len
,
uri
);
write_output_buffer
(
This
->
output
,
ltW
,
ARRAY_SIZE
(
ltW
));
write_output_qname
(
This
->
output
,
prefix
,
prefix_len
,
local_name
,
local_len
);
if
(
ns
)
write_output_qname
(
This
->
output
,
ns
->
prefix
,
ns
->
prefix_len
,
local_name
,
local_len
);
else
write_output_qname
(
This
->
output
,
prefix
,
prefix_len
,
local_name
,
local_len
);
writer_inc_indent
(
This
);
return
S_OK
;
...
...
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