tsolomko / SWCompression

A Swift framework for working with compression, archives and containers.
MIT License
237 stars 41 forks source link

[CRASH] LittleEndianByteReader.swift:33:20 #26

Closed Lakr233 closed 3 years ago

Lakr233 commented 3 years ago

I've been using your code in production for my project Saily, and found this issue in Bugsnag backend.

0  libswiftFoundation.dylib Data.subscript.getter
1  chromatic                LittleEndianByteReader.byte() (LittleEndianByteReader.swift:33:20)
2  chromatic                specialized static LZMA2.decompress(data:) (LZMA2.swift:26:54)
3  chromatic                static LZMA2.decompress(data:) (<compiler-generated>)
4  chromatic                RepositoryCenter.downloadUpdatePackage(withBaseUrl:suffix:) (RepositoryCenter+Downloader.swift:131:44)
5  chromatic                closure tsolomko/BitByteData#1 in closure #6 in RepositoryCenter.asyncUpdate(target:onComplete:) (RepositoryCenter+Internal.swift:304:39)
6  chromatic                partial apply for closure tsolomko/BitByteData#1 in closure #6 in RepositoryCenter.asyncUpdate(target:onComplete:) (<compiler-generated>)
7  chromatic                thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
8  libdispatch.dylib        __dispatch_call_block_and_release
9 ...
libdispatch etc, etc

Currently I can not provide you the sample data about it, but will back to you if I get anything new.

Here is the full report in casue you need it.

bugsnag_error_stacktrace_EXC_BREAKPOINT_event.txt

In my project, line 33 seems to be return data[offset].

public func byte() -> UInt8 {
    defer { offset += 1 }
    return data[offset] // <--
}

And in SWCompression, (LZMA2.swift:26:54)

public static func decompress(data: Data) throws -> Data {
    let byteReader = LittleEndianByteReader(data: data)
//                                                   *
    return try decompress(byteReader, byteReader.byte()) // <--
}
tsolomko commented 3 years ago

The line numbers seem to be off by 1 for some reason, but from what I can see from those lines, it seems you're trying to process an empty Data which causes this issue, though to confirm this I will need to look at the sample data. That said, the empty Data is not a good reason for a crash...

LittleEndianByteReader does what it was designed to do: it is the responsibility of the "user" of BitByteData to check that there is any data remaining before calling any methods. So the oversight is on SWCompression's part, and additional checks should be added there to prevent such crashes. For this reason, I transferred this issue to that repository.

The fix should be relatively straightforward, and it shouldn't take long time for me to implement it. However, since iOS 15 is coming next week, I suspect a new Swift will be released as well, so I will wait until it happens to check that nothing is broken due to that.

tsolomko commented 3 years ago

Fixed in 4.6.1.