Skip to content

Commit fb6c82e

Browse files
committed
SR-7570: Initializing XMLDocument crashes on Linux with nodePreserveAll
- Converting the options to an Int32 caused an overflow, so make _CFXMLDocPtrFromDataWithOptions() take the options as an unsigned int instead.
1 parent 1d31458 commit fb6c82e

File tree

4 files changed

+20
-3
lines changed

4 files changed

+20
-3
lines changed

CoreFoundation/Parsing.subproj/CFXMLInterface.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ _CFXMLNodePtr _CFXMLNodeHasProp(_CFXMLNodePtr node, const char* propertyName) {
909909
return xmlHasProp(node, (const xmlChar*)propertyName);
910910
}
911911

912-
_CFXMLDocPtr _CFXMLDocPtrFromDataWithOptions(CFDataRef data, int options) {
912+
_CFXMLDocPtr _CFXMLDocPtrFromDataWithOptions(CFDataRef data, unsigned int options) {
913913
uint32_t xmlOptions = 0;
914914

915915
if ((options & _kCFXMLNodePreserveWhitespace) == 0) {

CoreFoundation/Parsing.subproj/CFXMLInterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ CFStringRef _Nullable _CFXMLCopyPathForNode(_CFXMLNodePtr node);
199199

200200
_CFXMLNodePtr _Nullable _CFXMLNodeHasProp(_CFXMLNodePtr node, const char* propertyName);
201201

202-
_CFXMLDocPtr _CFXMLDocPtrFromDataWithOptions(CFDataRef data, int options);
202+
_CFXMLDocPtr _CFXMLDocPtrFromDataWithOptions(CFDataRef data, unsigned int options);
203203

204204
CFStringRef _Nullable _CFXMLNodeCopyLocalName(_CFXMLNodePtr node);
205205
CFStringRef _Nullable _CFXMLNodeCopyPrefix(_CFXMLNodePtr node);

Foundation/XMLDocument.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ open class XMLDocument : XMLNode {
9292
@abstract Returns a document created from data. Parse errors are returned in <tt>error</tt>.
9393
*/
9494
public init(data: Data, options mask: XMLNode.Options = []) throws {
95-
let docPtr = _CFXMLDocPtrFromDataWithOptions(data._cfObject, Int32(mask.rawValue))
95+
let docPtr = _CFXMLDocPtrFromDataWithOptions(data._cfObject, UInt32(mask.rawValue))
9696
super.init(ptr: _CFXMLNodePtr(docPtr))
9797

9898
if mask.contains(.documentValidate) {

TestFoundation/TestXMLDocument.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class TestXMLDocument : LoopbackServerTest {
3333
("test_createElement", test_createElement),
3434
("test_addNamespace", test_addNamespace),
3535
("test_removeNamespace", test_removeNamespace),
36+
("test_optionPreserveAll", test_optionPreserveAll),
3637
]
3738
}
3839

@@ -510,6 +511,22 @@ class TestXMLDocument : LoopbackServerTest {
510511

511512
XCTAssert(doc.rootElement()?.elements(forLocalName: "prop", uri: "DAV:").first?.name == "D:prop", "failed to get elements, got \(doc.rootElement()?.elements(forLocalName: "prop", uri: "DAV:").first as Any)")
512513
}
514+
515+
func test_optionPreserveAll() {
516+
let xmlString = """
517+
<?xml version="1.0" encoding="UTF-8"?>
518+
<document>
519+
</document>
520+
"""
521+
522+
let data = xmlString.data(using: .utf8)!
523+
guard let document = try? XMLDocument(data: data, options: .nodePreserveAll) else {
524+
XCTFail("XMLDocument with options .nodePreserveAll")
525+
return
526+
}
527+
let expected = xmlString.lowercased() + "\n"
528+
XCTAssertEqual(expected, String(describing: document))
529+
}
513530
}
514531

515532
fileprivate extension XMLNode {

0 commit comments

Comments
 (0)