{"record":{"id":"74a5c393e0ff6e6a","repo":"shwenzhang/AndResGuard","slug":"writetablenamestringblock-utf-16le-length-is-different-name","errorCode":null,"errorMessage":"writeTableNameStringBlock UTF-16LE length is different  name %d, tempByte %d\n","messagePattern":"writeTableNameStringBlock UTF-16LE length is different  name (.+?), tempByte (.+?)\n","errorType":"exception","errorClass":"AndrolibException","httpStatus":null,"severity":"error","filePath":"AndResGuard-core/src/main/java/com/tencent/mm/androlib/res/decoder/StringBlock.java","lineNumber":304,"sourceCode":"          byte[] tempByte = name.getBytes(Charset.forName(\"UTF-8\"));\n          if (name.length() != tempByte.length) {\n            throw new AndrolibException(String.format(\n                \"writeTableNameStringBlock UTF-8 length is different  name %d, tempByte %d\\n\",\n                name.length(),\n                tempByte.length\n            ));\n          }\n          System.arraycopy(tempByte, 0, strings, offset, tempByte.length);\n          offset += name.length();\n          strings[offset++] = NULL;\n          totalSize += name.length() + 1;\n        } else {\n          writeShort(strings, offset, (short) name.length());\n          offset += 2;\n          totalSize += 2;\n          byte[] tempByte = name.getBytes(Charset.forName(\"UTF-16LE\"));\n          if ((name.length() * 2) != tempByte.length) {\n            throw new AndrolibException(String.format(\n                \"writeTableNameStringBlock UTF-16LE length is different  name %d, tempByte %d\\n\",\n                name.length(),\n                tempByte.length\n            ));\n          }\n          System.arraycopy(tempByte, 0, strings, offset, tempByte.length);\n          offset += tempByte.length;\n          strings[offset++] = NULL;\n          strings[offset++] = NULL;\n          totalSize += tempByte.length + 2;\n        }\n      }\n    }\n    //要保证string size 是4的倍数,要补零\n    int size = totalSize - stringsOffset;\n    if ((size % 4) != 0) {\n      int add = 4 - (size % 4);\n      for (i = 0; i < add; i++) {","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/com/tencent/mm/androlib/res/decoder/StringBlock.java#L286-L322","documentation":"The UTF-16LE branch of writeTableNameStringBlock writes name.length() as the length field and then requires the UTF-16LE encoding to occupy exactly length*2 bytes. The check fails for names containing supplementary (surrogate-pair) characters, where the char count and encoded size relationship breaks the writer's assumptions, and for pathological length values.","triggerScenarios":"writeTableNameStringBlock with block.m_isUTF8 == false and a name where name.getBytes(UTF_16LE).length != name.length()*2 (surrogate pairs/emoji in resource names).","commonSituations":"Resource names with emoji or astral-plane characters; apps with creatively named resources processed through AndResGuard.","solutions":["Rename resources containing emoji or supplementary characters to ASCII identifiers.","Keep resource-name obfuscation enabled so original names never reach the string-pool writer.","Patch validation to compare encoded length against the value actually written (counting code points).","Find the offending name in the message and edit it in the resource sources."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"static boolean utf16Simple(String name) {\n  return name.getBytes(StandardCharsets.UTF_16LE).length == name.length() * 2\n      && name.codePoints().allMatch(cp -> cp <= 0xFFFF);\n}\n// gate resource names on utf16Simple before processing","typeGuard":null,"tryCatchPattern":"try { ... } catch (AndrolibException e) { if (e.getMessage().contains(\"UTF-16LE length is different\")) { /* fail the build naming the offending resource from the message */ } else throw e; }","preventionTips":["Forbid emoji and astral-plane characters in resource names.","Prefer UTF-8 pools with short ASCII names so the strict checks pass trivially.","Test AndResGuard output on release builds before shipping.","Audit third-party AAR resources for exotic names during dependency review."],"tags":["android","resources-arsc","utf-16","encoding"],"backgroundTag":"encoding-length-mismatch","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"}