Skip to content

Commit

Permalink
Merge pull request #90 from onevcat/fix/size-overflow
Browse files Browse the repository at this point in the history
Fix a size overflow when calculate data length
  • Loading branch information
onevcat authored Aug 29, 2019
2 parents 332578c + 526b978 commit a0dd8e5
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 6 deletions.
7 changes: 7 additions & 0 deletions APNGKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
4B7D4ED61B9559BF005C0598 /* filter_neon_intrinsics.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B7D4ED41B9559BF005C0598 /* filter_neon_intrinsics.c */; };
4B7D4ED71B9559BF005C0598 /* filter_neon.S in Sources */ = {isa = PBXBuildFile; fileRef = 4B7D4ED51B9559BF005C0598 /* filter_neon.S */; };
4B7D4ED91B955CBF005C0598 /* arm_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B7D4ED81B955CBF005C0598 /* arm_init.c */; };
4BA1EFA7231767BE00D6D06C /* malformed-size.apng in Resources */ = {isa = PBXBuildFile; fileRef = 4BA1EFA6231767BD00D6D06C /* malformed-size.apng */; };
4BA1EFA8231767BE00D6D06C /* malformed-size.apng in Resources */ = {isa = PBXBuildFile; fileRef = 4BA1EFA6231767BD00D6D06C /* malformed-size.apng */; };
4BF022041B94442800F00CDE /* APNGImageViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF022031B94442800F00CDE /* APNGImageViewTests.swift */; };
B25269641E8FD9840096A0A7 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = B25269631E8FD9840096A0A7 /* libz.tbd */; };
B25269661E8FDA090096A0A7 /* GCDTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B19504F1E6D21670047B7DE /* GCDTimer.swift */; };
Expand Down Expand Up @@ -185,6 +187,7 @@
4B7D4ED41B9559BF005C0598 /* filter_neon_intrinsics.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = filter_neon_intrinsics.c; sourceTree = "<group>"; };
4B7D4ED51B9559BF005C0598 /* filter_neon.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = filter_neon.S; sourceTree = "<group>"; };
4B7D4ED81B955CBF005C0598 /* arm_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arm_init.c; sourceTree = "<group>"; };
4BA1EFA6231767BD00D6D06C /* malformed-size.apng */ = {isa = PBXFileReference; lastKnownFileType = file; name = "malformed-size.apng"; path = "TestImages/malformed-size.apng"; sourceTree = SOURCE_ROOT; };
4BF022031B94442800F00CDE /* APNGImageViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = APNGImageViewTests.swift; sourceTree = "<group>"; };
B252695A1E8FD8EA0096A0A7 /* APNGKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = APNGKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B25269631E8FD9840096A0A7 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; };
Expand Down Expand Up @@ -371,6 +374,7 @@
D1614E1C1B91EDD700050104 /* TestImages */ = {
isa = PBXGroup;
children = (
4BA1EFA6231767BD00D6D06C /* malformed-size.apng */,
4B5DF6831B99718C00C4D421 /* demo.png */,
D187FEE81B934F1B0013372D /* pyani.apng */,
D190199F1B93351300E16EDB /* elephant_apng.apng */,
Expand Down Expand Up @@ -575,6 +579,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
Expand Down Expand Up @@ -606,6 +611,7 @@
buildActionMask = 2147483647;
files = (
D1614E251B91EDE200050104 /* over_previous.apng in Resources */,
4BA1EFA7231767BE00D6D06C /* malformed-size.apng in Resources */,
D1614E331B91EE0000050104 /* minimalAPNG.apng in Resources */,
D19019A01B93351400E16EDB /* elephant_apng.apng in Resources */,
D1614E261B91EDE200050104 /* spinfox.apng in Resources */,
Expand All @@ -630,6 +636,7 @@
buildActionMask = 2147483647;
files = (
B25310201E90AA3200A65CEA /* ball.apng in Resources */,
4BA1EFA8231767BE00D6D06C /* malformed-size.apng in Resources */,
B253101F1E90AA3200A65CEA /* minimalAPNG.apng in Resources */,
B253101D1E90AA3200A65CEA /* elephant_apng.apng in Resources */,
B25310231E90AA3200A65CEA /* over_previous.apng in Resources */,
Expand Down
18 changes: 14 additions & 4 deletions APNGKit/Disassembler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
#endif

let signatureOfPNGLength = 8
let kMaxPNGSize: UInt32 = 1000000;
let kMaxPNGSize: UInt32 = 1000000
let kUserAllocMaxBytes: UInt32 = 100*1024*1024

// Reading callback for libpng
func readData(_ pngPointer: png_structp?, outBytes: png_bytep?, byteCountToRead: png_size_t) {
Expand All @@ -60,8 +61,8 @@ struct APNGMeta {

let firstFrameHidden: Bool

var length: UInt32 {
return height * rowBytes
var length: Int {
return Int(height) * Int(rowBytes)
}

var firstImageIndex: Int {
Expand Down Expand Up @@ -291,6 +292,10 @@ class Disassembler {
let height = png_get_image_height(pngPointer, infoPointer)
let rowBytes = UInt32(png_get_rowbytes(pngPointer, infoPointer))

if width > kMaxPNGSize || height > kMaxPNGSize {
throw DisassemblerError.fileSizeExceeded
}

// Decode acTL
var frameCount: UInt32 = 0, playCount: UInt32 = 0
png_get_acTL(pngPointer, infoPointer, &frameCount, &playCount)
Expand All @@ -312,7 +317,12 @@ class Disassembler {
frameCount: frameCount,
playCount: playCount,
firstFrameHidden: firstFrameHidden)


if meta.length > kUserAllocMaxBytes {
throw DisassemblerError.fileSizeExceeded

}

bufferFrame = Frame(length: meta.length, bytesInRow: meta.rowBytes)
currentFrame = Frame(length: meta.length, bytesInRow: meta.rowBytes)
apngMeta = meta
Expand Down
4 changes: 2 additions & 2 deletions APNGKit/Frame.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ class Frame {

var duration: TimeInterval = 0

init(length: UInt32, bytesInRow: UInt32) {
self.length = Int(length)
init(length: Int, bytesInRow: UInt32) {
self.length = length
self.bytesInRow = Int(bytesInRow)

self.bytes = UnsafeMutablePointer<UInt8>.allocate(capacity: self.length)
Expand Down
5 changes: 5 additions & 0 deletions APNGKitTests/APNGImageTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ class APNGImageTests: XCTestCase {
let image = APNGImage(named: "", in: .testBundle)
XCTAssertNil(image, "Empty string should result in nil")
}

func testOverflowImage() {
let image = APNGImage(named: "malformed-size", in: .testBundle)
XCTAssertNil(image)
}
}

private extension CocoaImage {
Expand Down
Binary file added TestImages/malformed-size.apng
Binary file not shown.

0 comments on commit a0dd8e5

Please sign in to comment.