master ohmu/fastfetch-openbsd / src / common / android / dex.c
ohmu  ·  2026-10-15
   1#include "common/android/dex.h"
   2#include "common/android/zip.h"
   3#include "common/debug.h"
   4#include "common/io.h"
   5#include "common/mallocHelper.h"
   6
   7#include <errno.h>
   8#include <fcntl.h>
   9#include <sys/mman.h>
  10#include <sys/stat.h>
  11
  12#ifdef FF_HAVE_ZLIB
  13    #include "common/zlib.h"
  14#endif
  15
  16// Offsets into the dex header, from https://source.android.com/docs/core/runtime/dex-format.
  17#define FF_DEX_ENDIAN_TAG 0x12345678u
  18#define FF_DEX_HEADER_SIZE 0x70
  19#define FF_DEX_OFF_FILE_SIZE 0x20
  20#define FF_DEX_OFF_ENDIAN_TAG 0x28
  21#define FF_DEX_OFF_STRING_IDS 0x3C
  22#define FF_DEX_OFF_TYPE_IDS_SIZE 0x40
  23#define FF_DEX_OFF_TYPE_IDS 0x44
  24#define FF_DEX_OFF_FIELD_IDS_SIZE 0x50
  25#define FF_DEX_OFF_FIELD_IDS 0x54
  26#define FF_DEX_OFF_METHOD_IDS_SIZE 0x58
  27#define FF_DEX_OFF_METHOD_IDS 0x5C
  28#define FF_DEX_OFF_CLASS_DEFS_SIZE 0x60
  29#define FF_DEX_OFF_CLASS_DEFS 0x64
  30
  31// class_def_item: [u32 class_idx][u32 access_flags][u32 superclass_idx][u32 interfaces_off]
  32// [u32 source_file_idx][u32 annotations_off][u32 class_data_off][u32 static_values_off]
  33#define FF_DEX_CLASS_DEF_SIZE 32
  34#define FF_DEX_OFF_CLASS_DEF_DATA 24
  35#define FF_DEX_OFF_CLASS_DEF_STATIC_VALUES 28
  36
  37// field_id_item: [u16 class_idx][u16 type_idx][u32 name_idx]
  38#define FF_DEX_FIELD_ID_SIZE 8
  39#define FF_DEX_OFF_FIELD_ID_TYPE 2
  40#define FF_DEX_OFF_FIELD_ID_NAME 4
  41
  42// method_id_item: [u16 class_idx][u16 proto_idx][u32 name_idx]
  43#define FF_DEX_METHOD_ID_SIZE 8
  44#define FF_DEX_OFF_METHOD_ID_NAME 4
  45
  46// code_item: [u16 registers_size][u16 ins_size][u16 outs_size][u16 tries_size][u32 debug_info_off]
  47// [u32 insns_size][u16 insns...]. Everything before the instruction stream is skipped by reading
  48// `insns_size` and starting `insns` where it ends.
  49#define FF_DEX_OFF_CODE_INSNS_SIZE 12
  50#define FF_DEX_OFF_CODE_INSNS 16
  51
  52// The seven `iget*` opcodes, which are how a method reads an instance field. `iput*` shares the same
  53// format and the same operand, and a `writeToParcel` does not store to a field, so one range covers
  54// both and the walk does not have to tell them apart.
  55#define FF_DEX_OP_FIELD_FIRST 0x52
  56#define FF_DEX_OP_FIELD_LAST 0x5F
  57
  58#define FF_DEX_ENTRY "classes.dex"
  59// How many `classesN.dex` entries a jar is walked for. A jar that spreads its classes over more
  60// than this still resolves everything in the entries that were walked; only a class that lives in
  61// one of the ones past the bound is reported as missing.
  62#define FF_DEX_MAX_ENTRIES 10
  63#define FF_DEX_MAGIC "dex\n"
  64
  65static uint16_t dexU16(const uint8_t* p) {
  66    return (uint16_t) ((uint16_t) p[0] | (uint16_t) ((uint16_t) p[1] << 8));
  67}
  68
  69static uint32_t dexU32(const uint8_t* p) {
  70    return (uint32_t) p[0] | ((uint32_t) p[1] << 8) | ((uint32_t) p[2] << 16) | ((uint32_t) p[3] << 24);
  71}
  72
  73// The dex header points at its tables with offsets that a corrupt or hostile file is free to set
  74// anywhere, including past the end of the mapping. Testing `end - p` alone does not catch that: once
  75// `p` is past `end` the subtraction is negative and casting it to size_t turns it into a huge value,
  76// so the comparison passes and the read goes off the end. Both directions have to be one test.
  77static bool dexInRange(const uint8_t* dex, const uint8_t* end, const uint8_t* p, size_t size) {
  78    return p >= dex && p <= end && (size_t) (end - p) >= size;
  79}
  80
  81// Same, for a table of `count` elements of `elementSize` bytes. `count` is 64-bit because the
  82// callers add one to an index that came out of the file, and doing that in 32 bits can wrap to zero
  83// and make the check pass for an index that is not in the table. Dividing rather than multiplying is
  84// what keeps a hostile `count` from wrapping the size_t on a 32-bit build -- armeabi-v7a is one, and
  85// there `count * 4` overflows for any count above 0x3FFFFFFF and the check passes again.
  86static bool dexTableInRange(const uint8_t* dex, const uint8_t* end, const uint8_t* p, uint64_t count, size_t elementSize) {
  87    if (p < dex || p > end) {
  88        return false;
  89    }
  90    return (size_t) (end - p) / elementSize >= count;
  91}
  92
  93// LEB128, at most five bytes for the 32-bit values a dex stores this way. `end` bounds every read:
  94// the lengths and indexes decoded here come out of the file, so a truncated one must not walk off
  95// the end. A read that runs into `end` yields what was decoded so far, and the callers treat the
  96// resulting value as untrusted -- it is either compared against another count or used as an index
  97// that is range checked in turn.
  98static uint32_t dexUleb128(const uint8_t** p, const uint8_t* end) {
  99    uint32_t value = 0;
 100    for (int shift = 0; shift <= 28; shift += 7) {
 101        if (*p >= end) {
 102            break;
 103        }
 104        const uint8_t byte = *(*p)++;
 105        value |= (uint32_t) (byte & 0x7f) << shift;
 106        if ((byte & 0x80) == 0) {
 107            break;
 108        }
 109    }
 110    return value;
 111}
 112
 113// The type tag a dex encoded_value carries in the low five bits of its header byte, per the
 114// `encoded_value` table of the dex format.
 115//
 116// VALUE_NULL and VALUE_BOOLEAN are the trap. Their value *is* the header -- the type for a null,
 117// the size nibble for a boolean -- and they carry **no payload bytes at all**, so the
 118// `((size - 1) << 5) | type` rule that describes every other tag does not describe them. Taking the
 119// size nibble at face value and reading one payload byte walks one byte too far, which pairs every
 120// field after that with the wrong value. It is not a hypothetical: `IAudioService$Stub` declares ten
 121// `PERMISSIONS_*` arrays that are all null, right behind its `DESCRIPTOR` string and ahead of its
 122// 324 transaction constants, and those ten spurious bytes made
 123// `TRANSACTION_getDevicesForAttributesUnprotected` read as 210 instead of 167 -- a code that reaches
 124// a different method. `IWifiManager$Stub` has none ahead of the field the wifi module reads, which
 125// is the only reason this went unnoticed.
 126//
 127// Naming VALUE_BOOLEAN also matters for a second reason: it is the tag a `static final boolean`
 128// carries, and treating it as VALUE_INT would hand back a boolean where an int was asked for.
 129typedef enum FFDexValueType : uint32_t {
 130    FF_DEX_VALUE_INT = 0x04,     // sign-extended; one to four payload bytes
 131    FF_DEX_VALUE_NULL = 0x1e,    // no payload
 132    FF_DEX_VALUE_BOOLEAN = 0x1f, // no payload; the boolean is in the header's size nibble
 133} FFDexValueType;
 134
 135// encoded_value: one header byte holding ((size - 1) << 5) | type, then that many payload bytes.
 136//
 137// The `static_values` array is not a list of ints: `IInterface.DESCRIPTOR` is a `static final
 138// String` and sits in it, and a real Stub class mixes ints, strings, nulls and booleans. So a value
 139// whose tag is not VALUE_INT is skipped -- its payload is stepped over to keep the walk aligned with
 140// the field list -- and only `isInt` reports whether the *wanted* field ended up being one. Failing
 141// on the first non-int instead would abort on `DESCRIPTOR`, before the transaction constants that
 142// follow it are ever reached. Measured on a device: `IWifiManager$Stub` carries 347 static fields
 143// whose values are mostly VALUE_INT but include that string, and `getConnectionInfo` is 98 there.
 144//
 145// A payload wider than four bytes is not an int either, and the byte count is what keeps a size
 146// field read out of a corrupt file from shifting past the end. Reading through 64 bits keeps every
 147// shift in range while counting down; `end` is what keeps a truncated payload from running off the
 148// end of the mapping.
 149static bool dexEncodedValue(const uint8_t** p, const uint8_t* end, int32_t* result, bool* isInt) {
 150    if (*p >= end) {
 151        return false;
 152    }
 153    const uint8_t header = *(*p)++;
 154    const uint32_t type = (uint32_t) (header & 0x1f);
 155
 156    // The two tags whose value is the header byte itself. Returning here is what keeps the walk in
 157    // step; `isInt` is false because neither is an int.
 158    if (type == FF_DEX_VALUE_NULL || type == FF_DEX_VALUE_BOOLEAN) {
 159        *result = 0;
 160        *isInt = false;
 161        return true;
 162    }
 163
 164    const uint32_t size = (uint32_t) (header >> 5) + 1;
 165    if (size > 8) {
 166        return false;
 167    }
 168
 169    uint64_t value = 0;
 170    for (uint32_t i = 0; i < size; ++i) {
 171        if (*p >= end) {
 172            return false;
 173        }
 174        if (i < sizeof(value)) {
 175            value |= (uint64_t) (*(*p)++) << (i * 8);
 176        } else {
 177            (void) *(*p)++;
 178        }
 179    }
 180
 181    *isInt = type == FF_DEX_VALUE_INT && size <= sizeof(uint32_t);
 182    if (*isInt) {
 183        // VALUE_INT is sign-extended from its own width, not from 32 bits: a one-byte -1 is written
 184        // as `21 ff`, one byte of 0xff, and has to come back as -1 rather than 255.
 185        const uint32_t bits = size * 8;
 186        if ((value & (1ull << (bits - 1))) != 0) {
 187            value |= ~((1ull << bits) - 1);
 188        }
 189    }
 190    *result = (int32_t) (uint32_t) value;
 191    return true;
 192}
 193
 194// string_data_item: a uleb128 length in UTF-16 code units, then MUTF-8 bytes and a NUL terminator.
 195// The descriptors and field names looked up here are ASCII, where MUTF-8 and UTF-8 agree, so the
 196// bytes can be used as they are.
 197static const char* dexString(const uint8_t* dex, const uint8_t* end, uint32_t index) {
 198    const uint8_t* ids = dex + dexU32(dex + FF_DEX_OFF_STRING_IDS);
 199    // `string_ids_size` is not read: the check is that the entry `index` names lies inside the
 200    // mapping, which is what the read below needs, and the table is the only thing that can say it
 201    // without trusting a second field out of the same file.
 202    if (!dexTableInRange(dex, end, ids, (uint64_t) index + 1, 4)) {
 203        return nullptr;
 204    }
 205    const uint8_t* p = dex + dexU32(ids + (size_t) index * 4);
 206    if (p < dex || p >= end) {
 207        return nullptr;
 208    }
 209    (void) dexUleb128(&p, end);
 210    if (p >= end) {
 211        return nullptr;
 212    }
 213    return memchr(p, '\0', (size_t) (end - p)) != nullptr ? (const char*) p : nullptr;
 214}
 215
 216// One dex entry, validated. Every offset in the header comes out of the file, so each table is range
 217// checked before the walk uses it.
 218//
 219// `fieldIds` and `methodIds` are the two tables a class's own lists are resolved through: a
 220// class_data_item names its members by index into them, and the `name_idx` of the entry is what says
 221// which member it is. Holding them here rather than re-reading the header offset per class also
 222// turns the per-member bounds check into a count comparison, which has to happen before the index is
 223// multiplied out anyway -- on a 32-bit build `index * 8` wraps for a large enough index and the
 224// range check that follows passes again.
 225//
 226// `string_ids` is deliberately not held here: `dexString` checks the one entry it reads, and a table
 227// nothing walks in order does not need a second check.
 228typedef struct FFDexTables {
 229    const uint8_t* dex;
 230    const uint8_t* end;
 231    const uint8_t* types;
 232    uint32_t typeCount;
 233    const uint8_t* fieldIds;
 234    uint32_t fieldIdCount;
 235    const uint8_t* methodIds;
 236    uint32_t methodIdCount;
 237    const uint8_t* classes;
 238    uint32_t classCount;
 239} FFDexTables;
 240
 241static const char* dexOpen(const uint8_t* dex, size_t size, FFDexTables* tables) {
 242    if (size < FF_DEX_HEADER_SIZE || dexU32(dex + FF_DEX_OFF_ENDIAN_TAG) != FF_DEX_ENDIAN_TAG) {
 243        return "Not a dex file";
 244    }
 245    const uint32_t fileSize = dexU32(dex + FF_DEX_OFF_FILE_SIZE);
 246    if (fileSize > size || fileSize < FF_DEX_HEADER_SIZE) {
 247        return "The dex file size is out of range";
 248    }
 249    const uint8_t* end = dex + fileSize;
 250
 251    const uint8_t* types = dex + dexU32(dex + FF_DEX_OFF_TYPE_IDS);
 252    const uint32_t typeCount = dexU32(dex + FF_DEX_OFF_TYPE_IDS_SIZE);
 253    if (!dexTableInRange(dex, end, types, typeCount, 4)) {
 254        return "The dex type table is out of range";
 255    }
 256
 257    const uint8_t* fieldIds = dex + dexU32(dex + FF_DEX_OFF_FIELD_IDS);
 258    const uint32_t fieldIdCount = dexU32(dex + FF_DEX_OFF_FIELD_IDS_SIZE);
 259    if (!dexTableInRange(dex, end, fieldIds, fieldIdCount, FF_DEX_FIELD_ID_SIZE)) {
 260        return "The dex field table is out of range";
 261    }
 262
 263    const uint8_t* methodIds = dex + dexU32(dex + FF_DEX_OFF_METHOD_IDS);
 264    const uint32_t methodIdCount = dexU32(dex + FF_DEX_OFF_METHOD_IDS_SIZE);
 265    if (!dexTableInRange(dex, end, methodIds, methodIdCount, FF_DEX_METHOD_ID_SIZE)) {
 266        return "The dex method table is out of range";
 267    }
 268
 269    const uint8_t* classes = dex + dexU32(dex + FF_DEX_OFF_CLASS_DEFS);
 270    const uint32_t classCount = dexU32(dex + FF_DEX_OFF_CLASS_DEFS_SIZE);
 271    if (!dexTableInRange(dex, end, classes, classCount, FF_DEX_CLASS_DEF_SIZE)) {
 272        return "The dex class table is out of range";
 273    }
 274
 275    tables->dex = dex;
 276    tables->end = end;
 277    tables->types = types;
 278    tables->typeCount = typeCount;
 279    tables->fieldIds = fieldIds;
 280    tables->fieldIdCount = fieldIdCount;
 281    tables->methodIds = methodIds;
 282    tables->methodIdCount = methodIdCount;
 283    tables->classes = classes;
 284    tables->classCount = classCount;
 285    return nullptr;
 286}
 287
 288// The descriptor a type index names, e.g. "I", "[F" or "Landroid/os/Parcel;".
 289static const char* dexTypeString(const FFDexTables* tables, uint32_t typeIndex) {
 290    if (typeIndex >= tables->typeCount) {
 291        return nullptr;
 292    }
 293    return dexString(tables->dex, tables->end, dexU32(tables->types + (size_t) typeIndex * 4));
 294}
 295
 296// One pass over the type table, resolving the type index of every class that still has a request
 297// open. This pass is what a lookup costs: `framework.jar`'s classes.dex lists 8428 descriptors, each
 298// one a `string_data_item` read from a different part of a 51 MB mapping. Matching every request
 299// against the same pass is what makes a batch cheaper than the sum of its fields -- the descriptor is
 300// read once however many classes are being looked for, and the pass ends as soon as the last request
 301// has an index rather than at the end of the table.
 302//
 303// `typeIndexes` is parallel to `descriptors` and rebuilt here rather than kept across entries: a
 304// type index is a property of the entry's own table, and the next entry numbers its types
 305// differently.
 306static void dexFindTypes(const FFDexTables* tables, const char* const* descriptors, const uint8_t* settled, uint32_t* typeIndexes, uint32_t count) {
 307    uint32_t remaining = 0;
 308    for (uint32_t r = 0; r < count; ++r) {
 309        typeIndexes[r] = UINT32_MAX;
 310        if (!settled[r]) {
 311            ++remaining;
 312        }
 313    }
 314
 315    for (uint32_t i = 0; i < tables->typeCount && remaining > 0; ++i) {
 316        const char* descriptor = dexString(tables->dex, tables->end, dexU32(tables->types + (size_t) i * 4));
 317        if (descriptor == nullptr) {
 318            continue;
 319        }
 320        for (uint32_t r = 0; r < count; ++r) {
 321            if (settled[r] || typeIndexes[r] != UINT32_MAX || strcmp(descriptor, descriptors[r]) != 0) {
 322                continue;
 323            }
 324            typeIndexes[r] = i;
 325            --remaining;
 326        }
 327    }
 328}
 329
 330// The lists of a class_data_item, each positioned at its first entry.
 331//
 332// A class_data_item is `[uleb static_fields_size][uleb instance_fields_size][uleb direct_methods_size]
 333// [uleb virtual_methods_size]` followed by the four lists in that order, so the start of each list is
 334// only reachable by stepping over the one in front of it. That is done once here for the three
 335// readers that each want a different list: the static field reader pairs the first with the class's
 336// static value array, the write-sequence reader walks the methods, and the field-existence reader
 337// walks the second.
 338//
 339// A field entry is `[uleb field_idx_diff][uleb access_flags]` and a method entry is the same plus a
 340// trailing `[uleb code_off]`, which is the offset of the code_item holding its instructions -- or 0
 341// for a method with no body, an abstract or native one.
 342//
 343// Each of the four lists is delta-encoded from zero on its own, so the counts are kept apart rather
 344// than summed: a class routinely has a direct method and a virtual one under the same index, and one
 345// accumulator carried across the two method lists reads the second list's names out of the wrong end
 346// of the method table. The field lists are read the same way, which is why the reader of each one
 347// starts its index at zero rather than continuing from the list in front of it.
 348typedef struct FFDexClassData {
 349    const uint8_t* staticFields;
 350    const uint8_t* instanceFields;
 351    const uint8_t* methods;
 352    uint32_t staticFieldCount;
 353    uint32_t instanceFieldCount;
 354    uint32_t directMethodCount;
 355    uint32_t virtualMethodCount;
 356} FFDexClassData;
 357
 358// Steps over `count` field entries. A list that ends before its own count is a file that is not what
 359// it claims, not a short list: the count and the entries both come out of the same file.
 360static bool dexSkipFields(const uint8_t** p, const uint8_t* end, uint32_t count) {
 361    for (uint32_t i = 0; i < count; ++i) {
 362        if (*p >= end) {
 363            return false;
 364        }
 365        (void) dexUleb128(p, end); // field_idx_diff
 366        (void) dexUleb128(p, end); // access_flags
 367    }
 368    return true;
 369}
 370
 371static const char* dexReadClassData(const FFDexTables* tables, const uint8_t* classDef, FFDexClassData* data) {
 372    const uint8_t* dex = tables->dex;
 373    const uint8_t* end = tables->end;
 374    const uint32_t classDataOff = dexU32(classDef + FF_DEX_OFF_CLASS_DEF_DATA);
 375    if (classDataOff == 0) {
 376        // A class with no class_data_item declares nothing of its own -- its members are all
 377        // inherited. That is four empty lists, not a file that cannot be read, and the counts below
 378        // are what carry the answer.
 379        data->staticFields = nullptr;
 380        data->instanceFields = nullptr;
 381        data->methods = nullptr;
 382        data->staticFieldCount = 0;
 383        data->instanceFieldCount = 0;
 384        data->directMethodCount = 0;
 385        data->virtualMethodCount = 0;
 386        return nullptr;
 387    }
 388
 389    const uint8_t* p = dex + classDataOff;
 390    // One byte, so that the first uleb128 has something to read.
 391    if (!dexInRange(dex, end, p, 1)) {
 392        return "The dex class data is out of range";
 393    }
 394
 395    data->staticFieldCount = dexUleb128(&p, end);
 396    data->instanceFieldCount = dexUleb128(&p, end);
 397    data->directMethodCount = dexUleb128(&p, end);
 398    data->virtualMethodCount = dexUleb128(&p, end);
 399
 400    data->staticFields = p;
 401    if (!dexSkipFields(&p, end, data->staticFieldCount)) {
 402        return "The dex class data is truncated";
 403    }
 404    data->instanceFields = p;
 405    if (!dexSkipFields(&p, end, data->instanceFieldCount)) {
 406        return "The dex class data is truncated";
 407    }
 408    data->methods = p;
 409    return nullptr;
 410}
 411
 412// The class_def_item of the class that `typeIndex` names, or nullptr when this dex only references
 413// the class.
 414//
 415// Having a type index is not the same as being defined here: a dex lists every type it references in
 416// its type table, so a class that a later entry of the jar defines still has a type index in this
 417// one, with no class_def_item behind it. Only a class_def_item makes the answer this dex's, and
 418// without one the caller moves on to the next entry.
 419static const uint8_t* dexFindClassDef(const FFDexTables* tables, uint32_t typeIndex) {
 420    for (uint32_t i = 0; i < tables->classCount; ++i) {
 421        const uint8_t* classDef = tables->classes + (size_t) i * FF_DEX_CLASS_DEF_SIZE;
 422        if (dexU32(classDef) == typeIndex) {
 423            return classDef;
 424        }
 425    }
 426    return nullptr;
 427}
 428
 429// Walks the static field list of the class that `typeIndex` names and the class's static value array
 430// in step, writing the value of every request for that class whose field name matches. Both lists are
 431// ordered by field index and cover exactly the same fields -- when they do not, the pairing is not
 432// trustworthy and nothing is written.
 433//
 434// `defined` says whether this dex *defines* the class, which the caller needs: a request the class
 435// cannot answer has to be left open when the class belongs to a later entry of the jar and closed
 436// when it does not.
 437//
 438// A request this class cannot answer -- a field it does not declare, or one it declares as something
 439// other than an int -- is closed here rather than reported: the class is this dex's, so no later
 440// entry of the jar could give it a different answer, and one field the caller can live without must
 441// not hold back the rest of the batch. It is closed with the sentinel, and what this returns is only
 442// ever a dex that cannot be read, which is the one thing no later entry can fix.
 443static const char* dexClassStaticInts(const FFDexTables* tables, uint32_t typeIndex, const FFDexStaticIntRequest* requests, const uint32_t* typeIndexes, uint8_t* settled, uint32_t count, bool* defined) {
 444    const uint8_t* classDef = dexFindClassDef(tables, typeIndex);
 445    *defined = classDef != nullptr;
 446    if (classDef == nullptr) {
 447        return nullptr;
 448    }
 449
 450    const uint8_t* dex = tables->dex;
 451    const uint8_t* end = tables->end;
 452
 453    FFDexClassData classData;
 454    const char* error = dexReadClassData(tables, classDef, &classData);
 455    if (error != nullptr) {
 456        return error;
 457    }
 458
 459    // The static value array is parallel to the static field list and covers exactly the same fields,
 460    // which is what makes walking the two in step below meaningful. It is absent in two cases -- a
 461    // class with no static field, and a class none of whose static fields has a constant value -- and
 462    // the header writes 0 for it in both. The read is skipped rather than made against whatever byte
 463    // a zero offset points at, which is the dex magic and decodes as a four byte int.
 464    const uint8_t* fields = classData.staticFields;
 465    const uint8_t* values = dex;
 466    bool hasValues = false;
 467    if (classData.staticFieldCount > 0) {
 468        const uint32_t staticValuesOff = dexU32(classDef + FF_DEX_OFF_CLASS_DEF_STATIC_VALUES);
 469        if (staticValuesOff != 0) {
 470            values = dex + staticValuesOff;
 471            if (!dexInRange(dex, end, values, 1)) {
 472                return "The dex class data is out of range";
 473            }
 474            if (classData.staticFieldCount != dexUleb128(&values, end)) {
 475                return "The dex static fields and values do not pair up";
 476            }
 477            hasValues = true;
 478        }
 479    }
 480
 481    uint32_t fieldIndex = 0;
 482    for (uint32_t j = 0; j < classData.staticFieldCount; ++j) {
 483        // The two arrays are walked in step, so running out of either one is a truncation.
 484        if (fields >= end || (hasValues && values >= end)) {
 485            return "The dex static field list is truncated";
 486        }
 487
 488        const uint32_t fieldIndexDiff = dexUleb128(&fields, end); // field_idx_diff
 489        if (fieldIndexDiff > UINT32_MAX - fieldIndex) {
 490            return "The dex field index is out of range";
 491        }
 492        fieldIndex += fieldIndexDiff;
 493        (void) dexUleb128(&fields, end); // access_flags
 494        int32_t value = 0;
 495        // Left false when there is no value array, which closes the field with the sentinel below:
 496        // a class with no static value for the field has no answer for it.
 497        bool isInt = false;
 498        if (hasValues && !dexEncodedValue(&values, end, &value, &isInt)) {
 499            return "The dex static value list is truncated";
 500        }
 501
 502        if (fieldIndex >= tables->fieldIdCount) {
 503            return "The dex field table is out of range";
 504        }
 505        const char* name = dexString(dex, end, dexU32(tables->fieldIds + (size_t) fieldIndex * FF_DEX_FIELD_ID_SIZE + FF_DEX_OFF_FIELD_ID_NAME));
 506        if (name == nullptr) {
 507            continue;
 508        }
 509        for (uint32_t r = 0; r < count; ++r) {
 510            if (settled[r] || typeIndexes[r] != typeIndex || strcmp(name, requests[r].fieldName) != 0) {
 511                continue;
 512            }
 513            if (!isInt) {
 514                // The field exists but is not an int, so its value is not the constant asked for.
 515                // Closed the way a field the class does not declare is, because it is this dex's
 516                // answer too. The check is here rather than on the first non-int in the list because
 517                // the list legitimately holds strings (`DESCRIPTOR`) and booleans.
 518                *requests[r].result = FF_DEX_STATIC_INT_UNRESOLVED;
 519                settled[r] = 1;
 520                continue;
 521            }
 522            *requests[r].result = value;
 523            settled[r] = 1;
 524        }
 525    }
 526
 527    // The class is defined here, so a request of its own that went unanswered is one whose field the
 528    // class does not declare as a static field. Closed here for the same reason as above.
 529    for (uint32_t r = 0; r < count; ++r) {
 530        if (!settled[r] && typeIndexes[r] == typeIndex) {
 531            *requests[r].result = FF_DEX_STATIC_INT_UNRESOLVED;
 532            settled[r] = 1;
 533        }
 534    }
 535    return nullptr;
 536}
 537
 538// ---------------------------------------------------------------------------------------------
 539// Walking a method's instructions
 540// ---------------------------------------------------------------------------------------------
 541
 542// The width of every instruction, in code units. This is ART's `Instruction::SizeInCodeUnits`, and
 543// the walk below cannot stay on the instruction grid without it -- a walk that leaves the grid still
 544// produces a plausible-looking list of fields, which is what makes this worth a table rather than a
 545// guess. Unused and odex-only opcodes are 1 rather than 0, so that a byte which is not an instruction
 546// at all moves the walk on instead of leaving it where it is.
 547static const uint8_t dexOpcodeSize[256] = {
 548    /* 00 */ 1, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 1, 1, 1, 1,
 549    /* 10 */ 1, 1, 1, 2, 3, 2, 2, 3, 5, 2, 2, 3, 2, 1, 1, 2,
 550    /* 20 */ 2, 1, 2, 2, 3, 3, 3, 1, 1, 2, 3, 3, 3, 2, 2, 2,
 551    /* 30 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
 552    /* 40 */ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 553    /* 50 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 554    /* 60 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3,
 555    /* 70 */ 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1,
 556    /* 80 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 557    /* 90 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 558    /* a0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 559    /* b0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 560    /* c0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 561    /* d0 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
 562    /* e0 */ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 563    /* f0 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 3, 3, 2, 2,
 564};
 565
 566// The code_item at `codeOff`, with its instruction array range checked. nullptr is one that cannot
 567// be read: an offset outside the mapping, or an instruction count that runs past the end.
 568static const uint8_t* dexReadCode(const FFDexTables* tables, uint32_t codeOff) {
 569    const uint8_t* code = tables->dex + codeOff;
 570    if (!dexInRange(tables->dex, tables->end, code, FF_DEX_OFF_CODE_INSNS)) {
 571        return nullptr;
 572    }
 573    const uint32_t insnsSize = dexU32(code + FF_DEX_OFF_CODE_INSNS_SIZE);
 574    if (!dexTableInRange(tables->dex, tables->end, code + FF_DEX_OFF_CODE_INSNS, insnsSize, 2)) {
 575        return nullptr;
 576    }
 577    return code;
 578}
 579
 580// Records `name` and `type` as the next field of a write sequence, unless the name is already in it.
 581//
 582// An array field is read twice: once for its length, which is the count written ahead of the elements,
 583// and again inside the loop that writes them. A class cannot declare two instance fields under one
 584// name, so a repeat is always that reload, and the first read is where the field belongs in the
 585// sequence.
 586//
 587// A name or descriptor longer than the caller's buffer is refused rather than truncated: half a name
 588// matches nothing, which is indistinguishable from the field not being in the class at all. Refusing
 589// one field leaves the whole sequence unwritten, because a caller walking a sequence with a hole in
 590// it would read every field behind the hole from the wrong place.
 591static bool dexParcelFieldAdd(FFDexParcelField* fields, uint32_t* count, uint32_t capacity, const char* name, const char* type) {
 592    for (uint32_t i = 0; i < *count; ++i) {
 593        if (strcmp(fields[i].name, name) == 0) {
 594            return true;
 595        }
 596    }
 597    if (*count >= capacity) {
 598        return false;
 599    }
 600    const size_t nameSize = strlen(name) + 1;
 601    const size_t typeSize = strlen(type) + 1;
 602    if (nameSize > FF_DEX_PARCEL_FIELD_NAME_MAX || typeSize > FF_DEX_PARCEL_FIELD_TYPE_MAX) {
 603        return false;
 604    }
 605    memcpy(fields[*count].name, name, nameSize);
 606    memcpy(fields[*count].type, type, typeSize);
 607    ++*count;
 608    return true;
 609}
 610
 611// Walks the instruction grid of a code_item and records every instance field the method reads, in the
 612// order it reads them -- which is the order `writeToParcel` puts them on the wire.
 613//
 614// The grid is followed by opcode width, so the walk only ever lands on an instruction start, and it
 615// stops at the first payload pseudo-instruction. A `switch` or a `fill-array-data` leaves one behind
 616// every reachable instruction; its contents are data rather than instructions, and stepping into it
 617// desynchronises the grid for good.
 618//
 619// `iget*` and `iput*` share a format and put the field index in the code unit behind the opcode in
 620// both, which is what lets one test cover the whole range. A `writeToParcel` does not store to a
 621// field, so the `iput` half is never taken -- it is in the range because splitting it would be a
 622// claim about the method that the opcode does not make.
 623static const char* dexWalkParcelFields(const FFDexTables* tables, const uint8_t* code, FFDexParcelField* fields, uint32_t capacity, uint32_t* count) {
 624    *count = 0;
 625    const uint8_t* dex = tables->dex;
 626    const uint8_t* end = tables->end;
 627    const uint32_t insnsSize = dexU32(code + FF_DEX_OFF_CODE_INSNS_SIZE);
 628    const uint8_t* insns = code + FF_DEX_OFF_CODE_INSNS;
 629
 630    for (uint32_t i = 0; i < insnsSize;) {
 631        const uint16_t unit = dexU16(insns + (size_t) i * 2);
 632        // The three payload pseudo-instructions put their ident in the high byte and zero in the low
 633        // one. `nop` is the one instruction whose low byte is zero as well, and it is told apart by
 634        // the whole code unit being zero. Testing the high byte alone is what gets this wrong: a
 635        // `sparse-switch` over register 2 encodes as 0x022c, which is an instruction, not a payload.
 636        if ((unit & 0xFF) == 0 && unit != 0) {
 637            break;
 638        }
 639        const uint32_t opcode = unit & 0xFF;
 640        if (opcode >= FF_DEX_OP_FIELD_FIRST && opcode <= FF_DEX_OP_FIELD_LAST) {
 641            if (i + 1 >= insnsSize) {
 642                break;
 643            }
 644            const uint32_t fieldIndex = dexU16(insns + ((size_t) i + 1) * 2);
 645            if (fieldIndex >= tables->fieldIdCount) {
 646                return "The dex field table is out of range";
 647            }
 648            const uint8_t* fieldId = tables->fieldIds + (size_t) fieldIndex * FF_DEX_FIELD_ID_SIZE;
 649            const char* name = dexString(dex, end, dexU32(fieldId + FF_DEX_OFF_FIELD_ID_NAME));
 650            const char* type = dexTypeString(tables, dexU16(fieldId + FF_DEX_OFF_FIELD_ID_TYPE));
 651            if (name == nullptr || type == nullptr) {
 652                return "The dex field is not resolvable";
 653            }
 654            if (!dexParcelFieldAdd(fields, count, capacity, name, type)) {
 655                FF_DEBUG("\"%s\" (%s) does not fit a sequence of %u fields", name, type, capacity);
 656                *count = 0;
 657                return nullptr;
 658            }
 659        }
 660        i += dexOpcodeSize[opcode];
 661    }
 662    return nullptr;
 663}
 664
 665// Walks the instance field list of one `class_data_item` and writes `true` for every name it holds.
 666// The list is the caller's, so this answers one request's worth of names or several.
 667//
 668// This is the question a Parcelable whose layout is not field-driven needs: `DisplayCutout` reads
 669// everything through compiler-synthesised accessors, so the set of fields its class declares is the
 670// only thing that says how long its body is. It is asked as part of a write-sequence request rather
 671// than by a call of its own -- the list is already positioned by the `class_data_item` the sequence
 672// comes out of, and a separate call would repeat the whole walk to reach it.
 673static const char* dexMatchInstanceFields(const FFDexTables* tables, const uint8_t* fields, uint32_t fieldCount, const char* const* names, bool* results, uint32_t nameCount) {
 674    const uint8_t* dex = tables->dex;
 675    const uint8_t* end = tables->end;
 676
 677    uint32_t fieldIndex = 0;
 678    for (uint32_t j = 0; j < fieldCount; ++j) {
 679        if (fields >= end) {
 680            return "The dex class data is truncated";
 681        }
 682        const uint32_t fieldIndexDiff = dexUleb128(&fields, end); // field_idx_diff
 683        if (fieldIndexDiff > UINT32_MAX - fieldIndex) {
 684            return "The dex field index is out of range";
 685        }
 686        fieldIndex += fieldIndexDiff;
 687        (void) dexUleb128(&fields, end); // access_flags
 688
 689        if (fieldIndex >= tables->fieldIdCount) {
 690            return "The dex field table is out of range";
 691        }
 692        const char* name = dexString(dex, end, dexU32(tables->fieldIds + (size_t) fieldIndex * FF_DEX_FIELD_ID_SIZE + FF_DEX_OFF_FIELD_ID_NAME));
 693        if (name == nullptr) {
 694            continue;
 695        }
 696        for (uint32_t i = 0; i < nameCount; ++i) {
 697            if (!results[i] && strcmp(name, names[i]) == 0) {
 698                results[i] = true;
 699            }
 700        }
 701    }
 702    return nullptr;
 703}
 704
 705// Walks the method list of the class that `typeIndex` names, and for every request whose method name
 706// it holds walks that method's instructions. `defined` is what `dexClassStaticInts` reports, for the
 707// same reason.
 708//
 709// A request the class does not answer is closed with a count of 0 -- the count a caller reads as
 710// "this build does not write that class", which is the truth: the class is this dex's, so no later
 711// entry of the jar has the method either.
 712static const char* dexClassParcelFields(const FFDexTables* tables, uint32_t typeIndex, const FFDexParcelRequest* requests, const uint32_t* typeIndexes, uint8_t* settled, uint32_t count, bool* defined) {
 713    const uint8_t* classDef = dexFindClassDef(tables, typeIndex);
 714    *defined = classDef != nullptr;
 715    if (classDef == nullptr) {
 716        return nullptr;
 717    }
 718
 719    const uint8_t* dex = tables->dex;
 720    const uint8_t* end = tables->end;
 721
 722    FFDexClassData classData;
 723    const char* error = dexReadClassData(tables, classDef, &classData);
 724    if (error != nullptr) {
 725        return error;
 726    }
 727
 728    // The instance fields first, out of the list the `class_data_item` has already positioned. A
 729    // request that asked for them is answered here whether or not it also asked for a sequence, and
 730    // one that asked for neither is settled by the loop at the end like any other.
 731    for (uint32_t r = 0; r < count; ++r) {
 732        if (settled[r] || typeIndexes[r] != typeIndex || requests[r].instanceFieldCount == 0) {
 733            continue;
 734        }
 735        error = dexMatchInstanceFields(
 736            tables, classData.instanceFields, classData.instanceFieldCount,
 737            requests[r].instanceFieldNames, requests[r].instanceFieldResults, requests[r].instanceFieldCount
 738        );
 739        if (error != nullptr) {
 740            return error;
 741        }
 742    }
 743
 744    const uint8_t* methods = classData.methods;
 745    // Two runs, each delta-encoded from zero on its own -- so the index is reset per run rather than
 746    // carried across, and a direct method and a virtual one under the same index both resolve.
 747    for (uint32_t list = 0; list < 2; ++list) {
 748        const uint32_t listCount = list == 0 ? classData.directMethodCount : classData.virtualMethodCount;
 749        uint32_t methodIndex = 0;
 750        for (uint32_t j = 0; j < listCount; ++j) {
 751            if (methods >= end) {
 752                return "The dex class data is truncated";
 753            }
 754            const uint32_t methodIndexDiff = dexUleb128(&methods, end); // method_idx_diff
 755            if (methodIndexDiff > UINT32_MAX - methodIndex) {
 756                return "The dex method index is out of range";
 757            }
 758            methodIndex += methodIndexDiff;
 759            (void) dexUleb128(&methods, end); // access_flags
 760            const uint32_t codeOff = dexUleb128(&methods, end);
 761
 762            if (methodIndex >= tables->methodIdCount) {
 763                return "The dex method table is out of range";
 764            }
 765            const char* name = dexString(dex, end, dexU32(tables->methodIds + (size_t) methodIndex * FF_DEX_METHOD_ID_SIZE + FF_DEX_OFF_METHOD_ID_NAME));
 766            if (name == nullptr) {
 767                continue;
 768            }
 769
 770            for (uint32_t r = 0; r < count; ++r) {
 771                // A request that left the sequence out is one that only wanted the instance fields,
 772                // which are already written; it has no method name to match against.
 773                if (settled[r] || typeIndexes[r] != typeIndex || requests[r].methodName == nullptr
 774                    || strcmp(name, requests[r].methodName) != 0) {
 775                    continue;
 776                }
 777                // A method with no body -- abstract, or native -- writes nothing, and the count stays 0.
 778                const uint8_t* code = codeOff == 0 ? nullptr : dexReadCode(tables, codeOff);
 779                if (codeOff != 0 && code == nullptr) {
 780                    return "The dex code is out of range";
 781                }
 782                if (code != nullptr) {
 783                    error = dexWalkParcelFields(tables, code, requests[r].fields, requests[r].capacity, requests[r].count);
 784                    if (error != nullptr) {
 785                        return error;
 786                    }
 787                }
 788                settled[r] = 1;
 789            }
 790        }
 791    }
 792
 793    // The class is defined here, so a request of its own that went unanswered is one whose method the
 794    // class does not declare. The count it already holds is the 0 that says so.
 795    for (uint32_t r = 0; r < count; ++r) {
 796        if (!settled[r] && typeIndexes[r] == typeIndex) {
 797            settled[r] = 1;
 798        }
 799    }
 800    return nullptr;
 801}
 802
 803// ---------------------------------------------------------------------------------------------
 804// Locating classes.dex
 805// ---------------------------------------------------------------------------------------------
 806
 807typedef struct FFDexMapping {
 808    uint8_t* mapped; // the jar, as mapped; nullptr once released
 809    size_t mappedSize;
 810} FFDexMapping;
 811
 812static void wrapDexMapping(FFDexMapping* mapping) {
 813    assert(mapping);
 814    if (mapping->mapped != nullptr) {
 815        munmap(mapping->mapped, mapping->mappedSize);
 816    }
 817}
 818
 819// Maps the jar read-only. The pages the walk touches are the only ones faulted in, which is what
 820// keeps a 52 MB framework.jar off the heap and out of the cost of a lookup. The mapping outlives the
 821// descriptor, so the descriptor is closed before this returns.
 822static const char* dexMapJar(const char* jarPath, FFDexMapping* mapping) {
 823    FF_AUTO_CLOSE_FD int fd = open(jarPath, O_RDONLY | O_CLOEXEC);
 824    if (fd < 0) {
 825        FF_DEBUG("open(%s) failed: %s", jarPath, strerror(errno));
 826        return "open(jar) failed";
 827    }
 828
 829    struct stat st = {};
 830    const int statStatus = fstat(fd, &st);
 831    if (statStatus != 0 || st.st_size <= 0) {
 832        FF_DEBUG("fstat(%s) reported %s (%lld bytes)", jarPath,
 833            statStatus != 0 ? strerror(errno) : "an empty file", (long long) st.st_size);
 834        return "fstat(jar) failed";
 835    }
 836    mapping->mappedSize = (size_t) st.st_size;
 837    mapping->mapped = mmap(nullptr, mapping->mappedSize, PROT_READ, MAP_PRIVATE, fd, 0);
 838    if (mapping->mapped == MAP_FAILED) {
 839        FF_DEBUG("mmap(%s, %zu bytes) failed: %s", jarPath, mapping->mappedSize, strerror(errno));
 840        mapping->mapped = nullptr;
 841        return "mmap(jar) failed";
 842    }
 843    return nullptr;
 844}
 845
 846// Locates `classesN.dex` in the jar's central directory. The walk that finds an entry is the same
 847// one the app label reader needs for an APK's resource table, so it lives in common/android/zip.h
 848// and this is the dex-specific half of the question: which name to ask for.
 849static const char* findDexEntry(const uint8_t* jar, size_t jarSize, const char* entry, const uint8_t** data, size_t* dataSize, uint32_t* uncompressedSize, uint16_t* method) {
 850    FFAndroidZipEntry found = {};
 851    const char* error = ffAndroidZipFindEntry(jar, jarSize, entry, &found);
 852    if (error != nullptr) {
 853        return error;
 854    }
 855    *data = found.payload;
 856    *dataSize = found.payloadSize;
 857    *uncompressedSize = found.uncompressedSize;
 858    *method = found.method;
 859    return nullptr;
 860}
 861
 862// Fallback for a jar whose entry is STORED but whose header has no sizes: the dex magic is then a
 863// literal run of bytes in the file, and the header that follows it validates or it does not. It
 864// only ever locates the *first* dex in the jar, so it is a fallback for `classes.dex` alone.
 865static const uint8_t* findDexMagic(const uint8_t* jar, size_t jarSize, size_t* dexSize) {
 866    for (size_t i = 0; i + FF_DEX_HEADER_SIZE <= jarSize; ++i) {
 867        if (memcmp(jar + i, FF_DEX_MAGIC, sizeof(FF_DEX_MAGIC) - 1) != 0) {
 868            continue;
 869        }
 870        const uint8_t* dex = jar + i;
 871        const uint32_t fileSize = dexU32(dex + FF_DEX_OFF_FILE_SIZE);
 872        if (dexU32(dex + FF_DEX_OFF_ENDIAN_TAG) != FF_DEX_ENDIAN_TAG) {
 873            continue;
 874        }
 875        if (fileSize < FF_DEX_HEADER_SIZE || fileSize > jarSize - i) {
 876            continue;
 877        }
 878        *dexSize = fileSize;
 879        return dex;
 880    }
 881    return nullptr;
 882}
 883
 884#ifdef FF_HAVE_ZLIB
 885static const char* inflateDex(const uint8_t* data, size_t dataSize, uint32_t uncompressedSize, uint8_t** out) {
 886    const char* error = ffZlibLoad(FF_ZLIB_INFLATE);
 887    if (error != nullptr) {
 888        FF_DEBUG("The dex cannot be inflated: %s", error);
 889        return error;
 890    }
 891
 892    // Released by the cleanup on every path out below; ownership moves to the caller by clearing
 893    // the pointer, which is also why no failure path has to free it by hand.
 894    FF_AUTO_FREE uint8_t* buffer = malloc(uncompressedSize);
 895    if (buffer == nullptr) {
 896        FF_DEBUG("malloc(%u) for the inflated dex failed", uncompressedSize);
 897        return "malloc failed";
 898    }
 899
 900    // `uncompress` is not usable here: a zip entry holds a raw deflate stream, without the two byte
 901    // zlib header that entry point insists on. A negative window size tells inflate to skip the
 902    // header, which is what the zip format expects.
 903    z_stream stream = {};
 904    stream.next_in = (Bytef*) data;
 905    stream.avail_in = (uInt) dataSize;
 906    stream.next_out = buffer;
 907    stream.avail_out = (uInt) uncompressedSize;
 908
 909    const int initStatus = inflateInit2(&stream, -MAX_WBITS);
 910    if (initStatus != Z_OK) {
 911        FF_DEBUG("inflateInit2() failed: zlib status %d", initStatus);
 912        return "inflateInit2 failed";
 913    }
 914    const int status = inflate(&stream, Z_FINISH);
 915    inflateEnd(&stream);
 916    if (status != Z_STREAM_END || stream.total_out != (uLong) uncompressedSize) {
 917        FF_DEBUG("inflate() returned %d, produced %lu of %u bytes",
 918            status, stream.total_out, uncompressedSize);
 919        return "Inflating the dex failed";
 920    }
 921
 922    *out = buffer;
 923    buffer = nullptr; // the caller owns it from here
 924    return nullptr;
 925}
 926#endif
 927
 928// The dex bytes of one jar entry, and the validated tables of the dex they hold.
 929typedef struct FFDexEntry {
 930    const uint8_t* data;
 931    size_t size;
 932    FFDexTables tables;
 933} FFDexEntry;
 934
 935// Locates `classesN.dex`, inflates it when the entry is deflated, and validates the header.
 936//
 937// `present` reports whether the jar holds the entry at all. A jar spreads its classes over as many
 938// entries as it needs and then simply runs out, so an entry that is not there ends the walk rather
 939// than failing it -- except for the first, which every jar has and which is where the magic scan
 940// stands in for a directory that cannot be read. `inflated` receives the buffer the caller has to
 941// release when the entry needed one, and is left alone otherwise.
 942static const char* dexOpenEntry(const FFDexMapping* mapping, uint32_t index, bool* present, uint8_t** inflated, FFDexEntry* entry) {
 943    // Wide enough for `classes999.dex`, which is the longest name `FF_DEX_MAX_ENTRIES` can ask for.
 944    char name[sizeof("classes999.dex")];
 945    if (index == 1) {
 946        memcpy(name, FF_DEX_ENTRY, sizeof(FF_DEX_ENTRY));
 947    } else {
 948        (void) snprintf(name, sizeof(name), "classes%u.dex", index);
 949    }
 950    *present = true;
 951
 952    const uint8_t* data = nullptr;
 953    size_t dataSize = 0;
 954    uint32_t uncompressedSize = 0;
 955    uint16_t method = FF_ZIP_METHOD_STORED;
 956    if (findDexEntry(mapping->mapped, mapping->mappedSize, name, &data, &dataSize, &uncompressedSize, &method) != nullptr) {
 957        if (index > 1) {
 958            // The magic scan only ever finds the first dex, so it cannot stand in for a later entry:
 959            // running past the end of the entries that exist ends the walk.
 960            *present = false;
 961            return nullptr;
 962        }
 963        data = findDexMagic(mapping->mapped, mapping->mappedSize, &dataSize);
 964        if (data == nullptr) {
 965            FF_DEBUG("Neither %s nor a dex magic signature is in the %zu byte jar", name, mapping->mappedSize);
 966            return "No dex in the jar";
 967        }
 968    } else if (method == FF_ZIP_METHOD_DEFLATED) {
 969        #ifdef FF_HAVE_ZLIB
 970        const char* error = inflateDex(data, dataSize, uncompressedSize, inflated);
 971        if (error != nullptr) {
 972            return error;
 973        }
 974        data = *inflated;
 975        dataSize = uncompressedSize;
 976        #else
 977        (void) inflated; // the parameter is only written on the inflating path
 978        return "The jar deflates its dex entries and fastfetch was built without zlib";
 979        #endif
 980    } else if (method != FF_ZIP_METHOD_STORED) {
 981        FF_DEBUG("%s uses compression method %u, only %u (stored) and %u (deflated) are handled",
 982            name, method, FF_ZIP_METHOD_STORED, FF_ZIP_METHOD_DEFLATED);
 983        return "A dex entry uses an unsupported compression method";
 984    }
 985    // A STORED entry needs no further work: `dataSize` already holds the `compressedSize` that
 986    // `findDexEntry` checked against the mapping, and for a STORED entry the payload is the file
 987    // itself. The header's `uncompressedSize` is deliberately not used for it -- nothing bounds that
 988    // value, so a corrupt one reaches past the end of the mapping, which is exactly what the dex
 989    // header would then be validated against.
 990
 991    entry->data = data;
 992    entry->size = dataSize;
 993    return dexOpen(entry->data, entry->size, &entry->tables);
 994}
 995
 996const char* ffDexStaticInts(const char* jarPath, const FFDexStaticIntRequest* requests, uint32_t count) {
 997    // Every request is written the sentinel before anything can fail, so that a caller reads a result
 998    // rather than whatever its own stack held there, however this returns. Nothing below has to
 999    // remember to do it on its way out.
1000    for (uint32_t r = 0; r < count; ++r) {
1001        *requests[r].result = FF_DEX_STATIC_INT_UNRESOLVED;
1002    }
1003    if (count == 0) {
1004        return nullptr;
1005    }
1006
1007    [[gnu::cleanup(wrapDexMapping)]] FFDexMapping mapping = {};
1008    const char* error = dexMapJar(jarPath, &mapping);
1009    if (error != nullptr) {
1010        return error;
1011    }
1012
1013    // One byte per request saying whether it is closed -- answered, or given up on -- the type index
1014    // it was found under in the entry being walked, and the descriptor that index was found for. All
1015    // three are sized from `count` rather than from a fixed bound, and all three are released by
1016    // their cleanup however this function returns.
1017    FF_AUTO_FREE uint8_t* settled = calloc(count, 1);
1018    FF_AUTO_FREE uint32_t* typeIndexes = malloc((size_t) count * sizeof(uint32_t));
1019    FF_AUTO_FREE const char** descriptors = malloc((size_t) count * sizeof(const char*));
1020    if (settled == nullptr || typeIndexes == nullptr || descriptors == nullptr) {
1021        FF_DEBUG("Allocating the tables for %u static int requests failed", count);
1022        return "malloc failed";
1023    }
1024    for (uint32_t r = 0; r < count; ++r) {
1025        descriptors[r] = requests[r].classDescriptor;
1026    }
1027
1028    // A jar spreads its classes over `classes.dex`, `classes2.dex`, `classes3.dex`, ... and the
1029    // class being looked for is in whichever one the build put it in: `IAudioService$Stub` is in the
1030    // second dex of framework.jar, while `IWifiManager$Stub` is in the first of framework-wifi.jar.
1031    // The entries are therefore tried in order, and the first one that defines the class answers.
1032    // The count is a bound on the walk, not a claim about the jar -- AOSP has never shipped more
1033    // than a handful, and a class that is in none of them is left unanswered either way.
1034    //
1035    // The walk ends as soon as the last request is closed, so an entry that holds every class asked
1036    // for -- which is what the modules here ask for, one class per interface -- costs one entry read
1037    // and one pass over its type table.
1038    uint32_t pending = count;
1039    for (uint32_t index = 1; index <= FF_DEX_MAX_ENTRIES && pending > 0; ++index) {
1040        // The decompressed dex, when the entry needed one. The cleanup releases it at the end of
1041        // the iteration, so every entry gets a buffer of its own and no way out of the loop -- an
1042        // early return included -- can leak one.
1043        FF_AUTO_FREE uint8_t* inflated = nullptr;
1044        FFDexEntry entry = {};
1045        bool present = false;
1046        error = dexOpenEntry(&mapping, index, &present, &inflated, &entry);
1047        if (error != nullptr) {
1048            // The dex cannot be read at all, which no later entry can fix.
1049            return error;
1050        }
1051        if (!present) {
1052            break;
1053        }
1054
1055        dexFindTypes(&entry.tables, descriptors, settled, typeIndexes, count);
1056
1057        // Every class this entry defines is walked once, however many of its fields were asked for.
1058        // A request whose class is not in this entry's type table keeps `UINT32_MAX` and is left for
1059        // the next entry; one whose class is only referenced here is left the same way by the walk
1060        // below, which is what `defined` reports.
1061        for (uint32_t r = 0; r < count; ++r) {
1062            if (settled[r] || typeIndexes[r] == UINT32_MAX) {
1063                continue;
1064            }
1065            const uint32_t typeIndex = typeIndexes[r];
1066            bool defined = false;
1067            error = dexClassStaticInts(&entry.tables, typeIndex, requests, typeIndexes, settled, count, &defined);
1068            if (error != nullptr) {
1069                // The dex cannot be read, which no later entry can fix.
1070                return error;
1071            }
1072            if (!defined) {
1073                // Only referenced here, so the class is left for the next entry -- and the requests
1074                // that share it are marked as walked, since one lookup of a class answers all of
1075                // them and the class table should not be scanned once per field.
1076                for (uint32_t s = r; s < count; ++s) {
1077                    if (typeIndexes[s] == typeIndex) {
1078                        typeIndexes[s] = UINT32_MAX;
1079                    }
1080                }
1081            }
1082        }
1083
1084        pending = 0;
1085        for (uint32_t r = 0; r < count; ++r) {
1086            if (!settled[r]) {
1087                ++pending;
1088            }
1089        }
1090    }
1091
1092    // What is still open is a class no entry of the jar defines. That is an answer like any other --
1093    // the results already hold the sentinel, written before the walk began -- so the only thing left
1094    // is to say so for a debug build, where the sentinel on its own does not tell "this build has no
1095    // such method" apart from "the reader went wrong".
1096    for (uint32_t r = 0; r < count; ++r) {
1097        if (*requests[r].result == FF_DEX_STATIC_INT_UNRESOLVED) {
1098            FF_DEBUG("\"%s\" is not a static int field of \"%s\"", requests[r].fieldName, requests[r].classDescriptor);
1099        }
1100    }
1101    return nullptr;
1102}
1103
1104const char* ffDexParcelFields(const char* jarPath, const FFDexParcelRequest* requests, uint32_t count) {
1105    // Every request is written its answers before anything can fail, so that a caller reads an answer
1106    // rather than whatever its own stack held there, however this returns. The instance fields go
1107    // first: `false` is what both "the class does not declare it" and "the jar cannot be read" mean,
1108    // and the walk below only ever turns one of them true.
1109    for (uint32_t r = 0; r < count; ++r) {
1110        if (requests[r].methodName != nullptr) {
1111            *requests[r].count = 0;
1112        }
1113        for (uint32_t i = 0; i < requests[r].instanceFieldCount; ++i) {
1114            requests[r].instanceFieldResults[i] = false;
1115        }
1116    }
1117    if (count == 0) {
1118        return nullptr;
1119    }
1120
1121    [[gnu::cleanup(wrapDexMapping)]] FFDexMapping mapping = {};
1122    const char* error = dexMapJar(jarPath, &mapping);
1123    if (error != nullptr) {
1124        return error;
1125    }
1126
1127    FF_AUTO_FREE uint8_t* settled = calloc(count, 1);
1128    FF_AUTO_FREE uint32_t* typeIndexes = malloc((size_t) count * sizeof(uint32_t));
1129    FF_AUTO_FREE const char** descriptors = malloc((size_t) count * sizeof(const char*));
1130    if (settled == nullptr || typeIndexes == nullptr || descriptors == nullptr) {
1131        FF_DEBUG("Allocating the tables for %u parcel field requests failed", count);
1132        return "malloc failed";
1133    }
1134    for (uint32_t r = 0; r < count; ++r) {
1135        descriptors[r] = requests[r].classDescriptor;
1136    }
1137
1138    uint32_t pending = count;
1139    for (uint32_t index = 1; index <= FF_DEX_MAX_ENTRIES && pending > 0; ++index) {
1140        FF_AUTO_FREE uint8_t* inflated = nullptr;
1141        FFDexEntry entry = {};
1142        bool present = false;
1143        error = dexOpenEntry(&mapping, index, &present, &inflated, &entry);
1144        if (error != nullptr) {
1145            // The dex cannot be read at all, which no later entry can fix.
1146            return error;
1147        }
1148        if (!present) {
1149            break;
1150        }
1151
1152        dexFindTypes(&entry.tables, descriptors, settled, typeIndexes, count);
1153
1154        for (uint32_t r = 0; r < count; ++r) {
1155            if (settled[r] || typeIndexes[r] == UINT32_MAX) {
1156                continue;
1157            }
1158            const uint32_t typeIndex = typeIndexes[r];
1159            bool defined = false;
1160            error = dexClassParcelFields(&entry.tables, typeIndex, requests, typeIndexes, settled, count, &defined);
1161            if (error != nullptr) {
1162                return error;
1163            }
1164            if (!defined) {
1165                for (uint32_t s = r; s < count; ++s) {
1166                    if (typeIndexes[s] == typeIndex) {
1167                        typeIndexes[s] = UINT32_MAX;
1168                    }
1169                }
1170            }
1171        }
1172
1173        pending = 0;
1174        for (uint32_t r = 0; r < count; ++r) {
1175            if (!settled[r]) {
1176                ++pending;
1177            }
1178        }
1179    }
1180
1181    // A request still holding 0 is one whose class no entry of the jar defines, or whose class does
1182    // not declare the method. Both are the same answer -- this build does not write that class -- and
1183    // for a debug build it is worth saying which of the two it was, since the count on its own does
1184    // not tell "this build has no such method" apart from "the reader went wrong". The same goes for
1185    // an instance field left `false`.
1186    for (uint32_t r = 0; r < count; ++r) {
1187        if (requests[r].methodName != nullptr && *requests[r].count == 0) {
1188            FF_DEBUG("The write sequence of \"%s.%s\" is not in the jar", requests[r].classDescriptor, requests[r].methodName);
1189        }
1190        for (uint32_t i = 0; i < requests[r].instanceFieldCount; ++i) {
1191            if (!requests[r].instanceFieldResults[i]) {
1192                FF_DEBUG("\"%s\" is not an instance field of \"%s\"", requests[r].instanceFieldNames[i], requests[r].classDescriptor);
1193            }
1194        }
1195    }
1196    return nullptr;
1197}