Skip to content

Commit

Permalink
Allow string section offset to overlap buckets
Browse files Browse the repository at this point in the history
  • Loading branch information
milend committed Aug 22, 2017
1 parent f72f8d8 commit 9783a57
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 10 deletions.
17 changes: 10 additions & 7 deletions Sources/HeaderMapCore/BinaryHeaderMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ struct BinaryHeaderMap {
MemoryLayout<UInt32>.size +
MemoryLayout<UInt32>.size;
}

static func headerPlusBucketsSize(
bucketCount: DataHeader.BucketCountType) -> Int {
let bucketsSectionSize = Int(bucketCount) * BinaryHeaderMap.Bucket.packedSize
return packedSize + bucketsSectionSize
}
}

enum Magic: UInt32 {
Expand Down Expand Up @@ -174,7 +180,9 @@ extension BinaryHeaderMap {

func getString(at offset: StringSectionOffset) -> String? {
let begin = Int(header.stringSectionOffset + offset.offset)
guard begin < data.count else { return nil }
let preambleSize = DataHeader.headerPlusBucketsSize(
bucketCount: header.bucketCount)
guard preambleSize <= begin, begin < data.count else { return nil }

let nullByteIndex = data.withUnsafeBytes {
(bytes: UnsafePointer<UInt8>) -> Int? in
Expand Down Expand Up @@ -285,16 +293,11 @@ func parseHeaderMap(data: Data) throws -> DataHeaderParseResult {
throw HeaderMapParseError.outOfBoundsStringSectionOffset
}

let bucketsSectionSize = Int(bucketCount) * BinaryHeaderMap.Bucket.packedSize
let headerAndBucketsSectionSize = H.packedSize + bucketsSectionSize
let headerAndBucketsSectionSize = H.headerPlusBucketsSize(bucketCount: bucketCount)
guard headerAndBucketsSectionSize <= data.count else {
throw HeaderMapParseError.bucketsSectionOverflow
}

guard headerAndBucketsSectionSize <= Int(stringSectionOffset) else {
throw HeaderMapParseError.invalidStringSectionOffset
}

return DataHeaderParseResult(
dataHeader: BinaryHeaderMap.DataHeader(
magic: magic,
Expand Down
3 changes: 0 additions & 3 deletions Sources/HeaderMapCore/HeaderMapError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public enum HeaderMapParseError: LocalizedError {
case outOfBoundsStringSectionOffset
case bucketCountNotPowerOf2(found: UInt32)
case bucketsSectionOverflow
case invalidStringSectionOffset
}

public enum HeaderMapCreateError: LocalizedError {
Expand Down Expand Up @@ -70,8 +69,6 @@ extension HeaderMapParseError {
return "Bucket count is not a power of 2, found \(buckets) buckets"
case .bucketsSectionOverflow:
return "Bucket section overflows"
case .invalidStringSectionOffset:
return "The string section offset is invalid"
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions Tests/HeaderMapCoreTests/HeaderMapTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,5 +137,12 @@ class HeaderMapTests: XCTestCase {
let hmapEntries = Set<HeaderMap.Entry>(hmap.makeEntryList())
XCTAssertEqual(Set(), hmapEntries)
}

func testStringOffsetInBucketSection() throws {
let hmapData = try loadFile(named: "Empty", extension: "hmap").unwrap()
let headerMap = try HeaderMap(data: hmapData)
let entries = Set<HeaderMap.Entry>(headerMap.makeEntryList())
XCTAssertEqual(entries, Set())
}
}

Binary file added Tests/HeaderMapCoreTests/TestFiles/Empty.hmap
Binary file not shown.

0 comments on commit 9783a57

Please sign in to comment.