Conversation
This still parses Android 33's `android.jar` successfully, but paves the way towards detecting new fields and flags that influence how newer resource tables should be parsed, rather than getting stuck reading random data.
…ype` chunks The original code was assuming that all non-empty `Type` entries were stored sequentially, directly after the index list and tightly packed together with no padding in between. Previously added assertions support this case, but this will no longer be fully correct with the introduction of a sparse `Type` in Android 34, and 16-bit offsets in Android 35. Note that a future patch should be removing the unusable index array that is exposed to the user: this byte-offset is no longer relevant to them when the elements have been parsed, and is terribly hard and error-prone to set up manually before serializing. This however becomes tedious to deal with in our writer.
The header for `TypeSpec` and `Type`, as well as the "index" mapping contain byte offsets, reserved fields and flags that are only usable for the binary parser and writer. Even though handling these are cumbersome at writing time (because of jumping back to the header or offsets array to write accurate byte positions after first serializing prior elements), that's still a lot more correct than leaving the user to **guess** what byte offsets to put into the vector/headers. That is otherwise going to be even more more complicated with the introduction of a new `SPARSE` `Type` flag in Android 34, and `OFFSET16` `Type` flag in Android 35.
Android 34 replaced most `Type` chunks with few entries with a new `SPARSE` list. Here the offset table is now a combination of a `u16` array index and a `u16` byte offset, allowing it to take up way less space in binary form when few elements are set while still reaching high(er) indexes (typically one or a handful of elements with an index in the hundreds or thousands).
Reserved field 1 is nog used for a number of types, though it has no impact on the what we need to parse.
Probably after using only 16-bits for the offset the behind the `SPARSE` flag, it was realized that 16-bit offsets could also reduce table size when applied to non-sparse `Type` lists.
Android 35 seemed to be on a quest to reduce resource table sizes by using smaller types for offsets, building on Android-34's sparse `Type` lists and now also using less bytes for compact entries where the value is only 4 bytes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumping the
target_sdk_versionto35results in hitting random asserts inside theResTableparser. Digging further shows that the parser wasn't that robust after all and happily ignored new fields and flags which should have affected how certain elements are parsed. New changes that Android made since 33:SPARSElists forTypechunk, instead of storing large arrays with manyNoneelements;TypeSpecis nowtypes_count;Typechunk;COMPACTTypeEntrys are now used for 4-byte values.Note that this PR only marginally tries to remove data-representation-specific pieces from the public
ChunksAPI. Callers will still have to guess a few fields that really should be handled internally, but since none of this is really actively used internally I did not bother.fn compile_mipmap()seems to spit out mostly bogus though, specifically forResTablePackageHeader.The existing tests already cover building and then parsing the table again, and also test all installed SDKs which happen to be the full
28..=35range on my machine; all succeed successfully.