Skip to content

Fix nested arrays parsing #29

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:4.0
// swift-tools-version:4.2
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down
116 changes: 47 additions & 69 deletions Sources/XMLParsing/Decoder/XMLDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -348,15 +348,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let int = number.intValue
guard NSNumber(value: int) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let int = Int(value)
guard Float(int) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return int
Expand All @@ -371,15 +369,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let int8 = number.int8Value
guard NSNumber(value: int8) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let int8 = Int8(value)
guard Float(int8) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return int8
Expand All @@ -394,15 +390,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let int16 = number.int16Value
guard NSNumber(value: int16) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let int16 = Int16(value)
guard Float(int16) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return int16
Expand All @@ -417,15 +411,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let int32 = number.int32Value
guard NSNumber(value: int32) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let int32 = Int32(value)
guard Float(int32) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return int32
Expand All @@ -440,15 +432,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let int64 = number.int64Value
guard NSNumber(value: int64) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let int64 = Int64(value)
guard Float(int64) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return int64
Expand All @@ -463,15 +453,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let uint = number.uintValue
guard NSNumber(value: uint) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let uint = UInt(value)
guard Float(uint) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return uint
Expand All @@ -486,15 +474,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let uint8 = number.uint8Value
guard NSNumber(value: uint8) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let uint8 = UInt8(value)
guard Float(uint8) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return uint8
Expand All @@ -509,15 +495,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let uint16 = number.uint16Value
guard NSNumber(value: uint16) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let uint16 = UInt16(value)
guard Float(uint16) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return uint16
Expand All @@ -532,15 +516,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let uint32 = number.uint32Value
guard NSNumber(value: uint32) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let uint32 = UInt32(value)
guard Float(uint32) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return uint32
Expand All @@ -555,15 +537,13 @@ extension _XMLDecoder {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: string)
}

let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let uint64 = number.uint64Value
guard NSNumber(value: uint64) == number else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(number)> does not fit in \(type)."))
let uint64 = UInt64(value)
guard Float(uint64) == value else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number <\(value)> does not fit in \(type)."))
}

return uint64
Expand All @@ -575,18 +555,15 @@ extension _XMLDecoder {
guard let string = value as? String else { return nil }

if let value = Double(string) {
let number = NSNumber(value: value)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard value != 1, value != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

let double = number.doubleValue
guard abs(double) <= Double(Float.greatestFiniteMagnitude) else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number \(number) does not fit in \(type)."))
guard abs(value) <= Double(Float.greatestFiniteMagnitude) else {
throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed XML number \(value) does not fit in \(type)."))
}

return Float(double)
return Float(value)
} else if case let .convertFromString(posInfString, negInfString, nanString) = self.options.nonConformingFloatDecodingStrategy {
if string == posInfString {
return Float.infinity
Expand All @@ -605,9 +582,10 @@ extension _XMLDecoder {

guard let string = value as? String else { return nil }

if let number = Decimal(string: string) as NSDecimalNumber? {
if let _ = Decimal(string: string) {
let number = NSDecimalNumber(string: string)

guard number !== kCFBooleanTrue, number !== kCFBooleanFalse else {
guard number != 1, number != 0 else {
throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value)
}

Expand Down
14 changes: 13 additions & 1 deletion Sources/XMLParsing/XMLStackParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,19 @@ internal class _XMLElement {
for childElement in children {
for child in childElement.value {
if let content = child.value {
node[childElement.key] = content
if var arr = node[childElement.key] as? [Any] {
arr.append(content)
node[childElement.key] = arr
} else if let v = node[childElement.key] {
let arr: [Any] = [v, content]
node[childElement.key] = arr
} else {
if let type = node["type"] as? String, type == "array" {
node[childElement.key] = [content]
} else {
node[childElement.key] = content
}
}
} else if !child.children.isEmpty || !child.attributes.isEmpty {
let newValue = child.flatten()

Expand Down