Skip to content

Commit

Permalink
Fix Integer type serialization for 32-bit platforms
Browse files Browse the repository at this point in the history
Motivation:

[RFC 9651](https://www.ietf.org/rfc/rfc9651.html) permits serializing an integer in the range of -999,999,999,999,999 to 999,999,999,999,999 inclusive ([Section 4.1.4-2.1.1](https://www.ietf.org/rfc/rfc9651.html#section-4.1.4-2.1.1)). As `RFC9651BareItem` takes values `integer` or `date` with an associated value of type `Int`, that range is implicitly more constrained on 32-bit platforms to a subset range of `-Int32.min` to `Int32.max` inclusive.

Modifications:

- Adjust `RFC9651BareItem` to take values `integer` or `date` with an associated value of type `Int64` instead, which is sufficient for the permitted range.

Result:

Compatibility for the Integer and Date Structured Types on 32-bit platforms.
  • Loading branch information
clintonpi committed Nov 29, 2024
1 parent 061d2a0 commit 0dde4ce
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 15 deletions.
10 changes: 5 additions & 5 deletions Sources/RawStructuredFieldValues/ComponentTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ extension BareItem {
self = .bool(b)

case .integer(let i):
self = .integer(i)
self = .integer(Int(i))

case .decimal(let d):
self = .decimal(d)
Expand Down Expand Up @@ -126,7 +126,7 @@ public enum RFC9651BareItem: Sendable {
case bool(Bool)

/// An integer item.
case integer(Int)
case integer(Int64)

/// A decimal item.
case decimal(PseudoDecimal)
Expand All @@ -142,7 +142,7 @@ public enum RFC9651BareItem: Sendable {
case token(String)

/// A date item.
case date(Int)
case date(Int64)

/// A display string item.
case displayString(String)
Expand All @@ -155,7 +155,7 @@ extension RFC9651BareItem: ExpressibleByBooleanLiteral {
}

extension RFC9651BareItem: ExpressibleByIntegerLiteral {
public init(integerLiteral value: Int) {
public init(integerLiteral value: Int64) {
self = .integer(value)
}
}
Expand Down Expand Up @@ -184,7 +184,7 @@ extension RFC9651BareItem {
self = .bool(b)

case .integer(let i):
self = .integer(i)
self = .integer(Int64(i))

case .decimal(let d):
self = .decimal(d)
Expand Down
4 changes: 2 additions & 2 deletions Sources/RawStructuredFieldValues/FieldParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ extension StructuredFieldValueParser {
}

private mutating func _parseAnIntegerOrDecimal(isDate: Bool) throws -> RFC9651BareItem {
var sign = 1
var sign = Int64(1)
var type = IntegerOrDecimal.integer

if let first = self.underlyingData.first, first == asciiDash {
Expand Down Expand Up @@ -304,7 +304,7 @@ extension StructuredFieldValueParser {
case .integer:
// This intermediate string is sad, we should rewrite this manually to avoid it.
// This force-unwrap is safe, as we have validated that all characters are ascii digits.
let baseInt = Int(String(decoding: integerBytes, as: UTF8.self), radix: 10)!
let baseInt = Int64(String(decoding: integerBytes, as: UTF8.self), radix: 10)!
let resultingInt = baseInt * sign

if isDate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ extension _StructuredFieldEncoder: SingleValueEncodingContainer {
}

func encode(_ data: Date) throws {
let date = Int(data.timeIntervalSince1970)
let date = Int64(data.timeIntervalSince1970)
try self.currentStackEntry.storage.insertBareItem(.date(date))
}

Expand Down Expand Up @@ -371,7 +371,7 @@ extension _StructuredFieldEncoder: SingleValueEncodingContainer {
}

private func _encodeFixedWidthInteger<T: FixedWidthInteger>(_ value: T) throws {
guard let base = Int(exactly: value) else {
guard let base = Int64(exactly: value) else {
throw StructuredHeaderError.integerOutOfRange
}
try self.currentStackEntry.storage.insertBareItem(.integer(base))
Expand Down Expand Up @@ -483,7 +483,7 @@ extension _StructuredFieldEncoder {
}

func append(_ value: Date) throws {
let date = Int(value.timeIntervalSince1970)
let date = Int64(value.timeIntervalSince1970)
try self.currentStackEntry.storage.appendBareItem(.date(date))
}

Expand Down Expand Up @@ -562,7 +562,7 @@ extension _StructuredFieldEncoder {
}

private func _appendFixedWidthInteger<T: FixedWidthInteger>(_ value: T) throws {
guard let base = Int(exactly: value) else {
guard let base = Int64(exactly: value) else {
throw StructuredHeaderError.integerOutOfRange
}
try self.currentStackEntry.storage.appendBareItem(.integer(base))
Expand Down Expand Up @@ -667,7 +667,7 @@ extension _StructuredFieldEncoder {

func encode(_ value: Date, forKey key: String) throws {
let key = self.sanitizeKey(key)
let date = Int(value.timeIntervalSince1970)
let date = Int64(value.timeIntervalSince1970)
try self.currentStackEntry.storage.insertBareItem(.date(date), atKey: key)
}

Expand Down Expand Up @@ -789,7 +789,7 @@ extension _StructuredFieldEncoder {
}

private func _encodeFixedWidthInteger<T: FixedWidthInteger>(_ value: T, forKey key: String) throws {
guard let base = Int(exactly: value) else {
guard let base = Int64(exactly: value) else {
throw StructuredHeaderError.integerOutOfRange
}
try self.currentStackEntry.storage.insertBareItem(.integer(base), atKey: key)
Expand Down
4 changes: 2 additions & 2 deletions Tests/StructuredFieldValuesTests/Fixtures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ struct StructuredHeaderTestFixture: Decodable {
enum JSONSchema: Decodable {
case dictionary([String: JSONSchema])
case array([JSONSchema])
case integer(Int)
case integer(Int64)
case double(Double)
case string(String)
case bool(Bool)
Expand All @@ -130,7 +130,7 @@ enum JSONSchema: Decodable {
self = .string(value)
} else if let bool = try? container.decode(Bool.self) {
self = .bool(bool)
} else if let value = try? container.decode(Int.self) {
} else if let value = try? container.decode(Int64.self) {
self = .integer(value)
} else if let value = try? container.decode(Double.self) {
self = .double(value)
Expand Down

0 comments on commit 0dde4ce

Please sign in to comment.