{"record":{"id":"0a0abe421039d5eb","repo":"shwenzhang/AndResGuard","slug":"writespecnamestringblock-s-utf-16le-length-is-different-name","errorCode":null,"errorMessage":"writeSpecNameStringBlock %s UTF-16LE length is different name %d, tempByte %d\n","messagePattern":"writeSpecNameStringBlock (.+?) 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":178,"sourceCode":"        if (name.length() != tempByte.length) {\n          throw new AndrolibException(String.format(\n              \"writeSpecNameStringBlock %s UTF-8 length is different name %d, tempByte %d\\n\",\n              name,\n              name.length(),\n              tempByte.length\n          ));\n        }\n        System.arraycopy(tempByte, 0, stringBytes, offset, tempByte.length);\n        offset += name.length();\n        stringBytes[offset++] = NULL;\n        totalSize += name.length() + 1;\n      } else {\n        writeShort(stringBytes, 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              \"writeSpecNameStringBlock %s UTF-16LE length is different name %d, tempByte %d\\n\",\n              name,\n              name.length(),\n              tempByte.length\n          ));\n        }\n        System.arraycopy(tempByte, 0, stringBytes, offset, tempByte.length);\n        offset += tempByte.length;\n        stringBytes[offset++] = NULL;\n        stringBytes[offset++] = NULL;\n        totalSize += tempByte.length + 2;\n      }\n      i++;\n    }\n    //要保证string size 是4的倍数,要补零\n    size = totalSize - stringsOffset;\n    if ((size % 4) != 0) {\n      int add = 4 - (size % 4);","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/com/tencent/mm/androlib/res/decoder/StringBlock.java#L160-L196","documentation":"The UTF-16LE branch of writeSpecNameStringBlock writes name.length() as the character count, then verifies that the actual UTF-16LE encoding uses exactly length*2 bytes. This fails when the name contains surrogate pairs (emoji, rare CJK), where Java's String.length() counts each surrogate separately but the UTF-16LE byte length still matches length*2 — or when the pool's declared encoding disagrees with the actual content, surfacing an encoding inconsistency.","triggerScenarios":"writeSpecNameStringBlock with isUTF8 == false and a resource name where name.getBytes(UTF_16LE).length != name.length()*2, typically due to surrogate-pair characters combined with the length-field encoding assumptions, or names longer than Short.MAX_VALUE.","commonSituations":"Resource names containing emoji or supplementary-plane characters; non-ASCII resource identifiers in apps localized with unusual names.","solutions":["Rename resources containing emoji/supplementary characters to plain ASCII identifiers.","Enable resource name obfuscation so original names never reach this writer.","Patch the check to count code points instead of chars when validating lengths.","Inspect the name printed in the message and fix it in the res source files."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"static boolean hasSupplementaryChars(String name) {\n  return name.codePoints().anyMatch(cp -> cp > 0xFFFF);\n}\n// reject or rename resources where hasSupplementaryChars(resName) is true","typeGuard":null,"tryCatchPattern":"try { ... } catch (AndrolibException e) { if (e.getMessage().contains(\"UTF-16LE length is different\")) { /* surface the resource name from the message; block release until renamed */ } else throw e; }","preventionTips":["Ban emoji/supplementary-plane characters in resource names by convention or lint rule.","Prefer enabling AndResGuard name obfuscation to eliminate exotic names early.","Review third-party library res/ contents for unusual names before integration.","Run obfuscation in CI on every release candidate."],"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"}