{"record":{"id":"2cc33ff34971681e","repo":"shwenzhang/AndResGuard","slug":"style-data-size-is-not-multiple-of-4-size","errorCode":null,"errorMessage":"Style data size is not multiple of 4 (${size}).","messagePattern":"Style data size is not multiple of 4 \\((.+?)\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"AndResGuard-core/src/main/java/com/tencent/mm/androlib/res/decoder/StringBlock.java","lineNumber":99,"sourceCode":"    Arrays.fill(block.m_stringOwns, -1);\n\n    if (styleCount != 0) {\n      block.m_styleOffsets = reader.readIntArray(styleCount);\n    }\n    {\n      int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) - stringsOffset;\n\n      if ((size % 4) != 0) {\n        throw new IOException(\"String data size is not multiple of 4 (\" + size + \").\");\n      }\n      block.m_strings = new byte[size];\n\n      reader.readFully(block.m_strings);\n    }\n    if (stylesOffset != 0) {\n      int size = (chunkSize - stylesOffset);\n      if ((size % 4) != 0) {\n        throw new IOException(\"Style data size is not multiple of 4 (\" + size + \").\");\n      }\n      block.m_styles = reader.readIntArray(size / 4);\n    }\n    return block;\n  }\n\n  public static int writeSpecNameStringBlock(\n          ExtDataInput reader, ExtDataOutput out, Map<String, Set<String>> specNames, Map<String, Integer> curSpecNameToPos)\n      throws IOException, AndrolibException {\n    int type = reader.readInt();\n    int chunkSize = reader.readInt();\n    int stringCount = reader.readInt();\n    int styleOffsetCount = reader.readInt();\n\n    if (styleOffsetCount != 0) {\n      throw new AndrolibException(String.format(\"writeSpecNameStringBlock styleOffsetCount != 0  styleOffsetCount %d\",\n          styleOffsetCount\n      ));","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/com/tencent/mm/androlib/res/decoder/StringBlock.java#L81-L117","documentation":"StringBlock.read() parses an Android resources.arsc string-pool chunk. When the chunk declares a styles section, the byte count from stylesOffset to the end of the chunk (chunkSize - stylesOffset) must be a multiple of 4, because styles are stored as int arrays. A misaligned size means the arsc chunk is truncated or corrupt, so the library throws IOException instead of reading garbage.","triggerScenarios":"Calling the API path that reads a string pool (e.g. StringBlock.read(reader)) on a chunk whose stylesOffset != 0 and where (chunkSize - stylesOffset) % 4 != 0, i.e. a malformed or hand-edited resources.arsc.","commonSituations":"Processing APKs whose resources.arsc was obfuscated, patched by another tool, truncated by a bad repackage, or built by non-standard tooling; reading corrupted or partially-downloaded APK files.","solutions":["Verify the input APK's resources.arsc is intact (re-obtain the original APK or rebuild it with aapt/aapt2).","Check that no other preprocessor modified resources.arsc before AndResGuard runs; disable conflicting tools in the build chain.","Update AndResGuard / Android build tools to a version that handles the arsc format produced by your AGP version.","Inspect chunkSize vs stylesOffset at StringBlock.java:99 with a hex dump of the arsc to confirm the chunk is truncated."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before parsing, sanity-check the arsc chunk header\nint expected = chunkSize - stylesOffset;\nif (stylesOffset != 0 && (expected % 4) != 0) {\n  throw new IllegalArgumentException(\"corrupt arsc chunk: size \" + expected + \" not 4-aligned\");\n}","typeGuard":null,"tryCatchPattern":"try { StringBlock block = StringBlock.read(reader); } catch (IOException e) { if (e.getMessage().contains(\"not multiple of 4\")) { /* reject APK as corrupt / fall back to original build */ } else throw e; }","preventionTips":["Only feed APKs built with standard aapt/aapt2 toolchains.","Never hand-edit or let third-party tools rewrite resources.arsc before obfuscation.","Validate APK integrity (signature/zip CRC) before processing.","Pin compatible AndResGuard + AGP versions in CI."],"tags":["android","resources-arsc","binary-parsing","corrupt-input"],"backgroundTag":"invalid-argument-format","analyzedSha":"e4df245d82f27d9a2d0dd108260a3510cbaba849","analyzedAt":"2026-09-12T17:49:07.798Z","contentChangedAt":"2026-09-12T17:49:07.798Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}