Skip to content

Commit 7a8a7fb

Browse files
authored
Merge pull request #27 from yahoojapan/feature/parse_invalid_character
catching invalid character error
2 parents 7e930e7 + 73fb8e2 commit 7a8a7fb

File tree

6 files changed

+58
-11
lines changed

6 files changed

+58
-11
lines changed

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ let str = """
119119
</ResultSet>
120120
"""
121121

122-
xml = try! XML.parse(string) // -> XML.Accessor
122+
xml = try! XML.parse(str) // -> XML.Accessor
123123
```
124124
+ from NSData
125125
```swift
@@ -136,11 +136,27 @@ let str = """
136136
</ResultSet>
137137
"""
138138

139-
let data = string.dataUsingEncoding(NSUTF8StringEncoding)
139+
let data = str.data(using: .utf8)
140140

141141
xml = XML.parse(data) // -> XML.Accessor
142142
```
143143

144+
+ with invalid character
145+
146+
```swift
147+
let srt = "<xmlopening>@ß123\u{1c}</xmlopening>"
148+
149+
let xml = XML.parse(str.data(using: .utf8))
150+
151+
if case .failure(XMLError.intrupptedParseError) = xml {
152+
print("invalid character")
153+
}
154+
155+
```
156+
157+
For more, see https://developer.apple.com/documentation/foundation/xmlparser/errorcode
158+
159+
144160
### 2. Access child Elements
145161
```swift
146162
let element = xml.ResultSet // -> XML.Accessor

SwiftyXMLParser/Error.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import Foundation
2626

2727
public enum XMLError: Error {
28-
case parseError
28+
case failToEncodeString
29+
case intrupptedParseError(rawError: Error)
2930
case accessError(description: String)
3031
}

SwiftyXMLParser/Parser.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,22 @@ import Foundation
2626

2727
extension XML {
2828
class Parser: NSObject, XMLParserDelegate {
29+
/// If it has value, Parser is interuppted by error. (e.g. using invalid character)
30+
/// So the result of parsing is missing.
31+
/// See https://developer.apple.com/documentation/foundation/xmlparser/errorcode
32+
private(set) var error: XMLError?
33+
2934
func parse(_ data: Data) -> Accessor {
3035
stack = [Element]()
3136
stack.append(documentRoot)
3237
let parser = XMLParser(data: data)
3338
parser.delegate = self
3439
parser.parse()
35-
return Accessor(documentRoot)
40+
if let error = error {
41+
return Accessor(error)
42+
} else {
43+
return Accessor(documentRoot)
44+
}
3645
}
3746

3847
override init() {
@@ -75,5 +84,9 @@ extension XML {
7584
}
7685
stack.removeLast()
7786
}
87+
88+
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
89+
error = .intrupptedParseError(rawError: parseError)
90+
}
7891
}
7992
}

SwiftyXMLParser/XML.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ open class XML {
104104
*/
105105
open class func parse(_ str: String) throws -> Accessor {
106106
guard let data = str.data(using: String.Encoding.utf8) else {
107-
throw XMLError.parseError
107+
throw XMLError.failToEncodeString
108108
}
109109

110110
return Parser().parse(data)
@@ -130,7 +130,7 @@ open class XML {
130130
*/
131131
open class func parse(_ str: String, trimming manner: CharacterSet) throws -> Accessor {
132132
guard let data = str.data(using: String.Encoding.utf8) else {
133-
throw XMLError.parseError
133+
throw XMLError.failToEncodeString
134134
}
135135

136136
return Parser(trimming: manner).parse(data)

SwiftyXMLParserTests/ParserTests.swift

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ class ParserTests: XCTestCase {
6161
}
6262

6363
let xml = XML.Parser().parse(data)
64-
if let _ = xml["ResultSet"].error {
65-
XCTFail("fail to parse")
64+
if case .failure(XMLError.intrupptedParseError) = xml {
65+
XCTAssert(true, "Parsed Failure because of the invalid character")
6666
} else {
67-
XCTAssert(true, "success to parse")
67+
XCTAssert(false, "fail")
6868
}
6969
}
7070

@@ -142,5 +142,22 @@ class ParserTests: XCTestCase {
142142
} else {
143143
XCTAssert(false, "fail")
144144
}
145-
}
145+
}
146+
147+
func testParseErrorToInvalidCharacter() {
148+
let str = "<xmlopening>@ß123\u{1c}</xmlopening>"
149+
let xml = XML.Parser().parse(str.data(using: .utf8)!)
150+
151+
if case .failure(XMLError.intrupptedParseError) = xml {
152+
XCTAssert(true, "Parsed Failure because of the invalid character")
153+
} else {
154+
XCTAssert(false, "fail")
155+
}
156+
}
157+
158+
func testNotParseErrorToInvalidCharacter() {
159+
let str = "<xmlopening>@ß123\u{1c}</xmlopening>".addingPercentEncoding(withAllowedCharacters: CharacterSet.controlCharacters.inverted)!
160+
let xml = XML.Parser().parse(str.data(using: .utf8)!)
161+
XCTAssertEqual("@ß123\u{1c}", xml["xmlopening"].text?.removingPercentEncoding, "Parsed Success and trim them")
162+
}
146163
}

SwiftyXMLParserTests/XMLTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class XMLTests: XCTestCase {
7070

7171

7272
func testSuccessParseFromDoublebyteSpace() {
73-
guard let xml = try? XML.parse("<Name> <Name>") else {
73+
guard let xml = try? XML.parse("<Name> </Name>") else {
7474
XCTFail("Fail Prase")
7575
return
7676
}

0 commit comments

Comments
 (0)