shwenzhang/AndResGuard · error · AndrolibException
writeTableNameStringBlock UTF-8 length is different name
Error message
writeTableNameStringBlock UTF-8 length is different name %d, tempByte %d
What it means
In the UTF-8 branch of writeTableNameStringBlock, the writer casts name.length() (Java UTF-16 char count) to a byte as the pool's length field and asserts the UTF-8 encoding length equals it. For non-ASCII names (multi-byte UTF-8) or names longer than 127 bytes, the lengths differ and AndrolibException is thrown.
Solutions
- Rename non-ASCII resource entries to ASCII-only names in the source project.
- Ensure AndResGuard's name obfuscation is enabled so the original (non-ASCII) names are replaced before writing.
- Patch the writer to encode the actual UTF-8 byte length instead of casting String.length().
- Identify the resource from the name field in the message and fix it in res/values.
Example fix
// before strings[offset++] = (byte) name.length(); strings[offset++] = (byte) name.length(); // after byte[] utf8 = name.getBytes(StandardCharsets.UTF_8); strings[offset++] = (byte) utf8.length; strings[offset++] = (byte) utf8.length;
Defensive patterns
Strategy: validation
Validate before calling
static boolean utf8Safe(String name) {
return name.getBytes(StandardCharsets.UTF_8).length == name.length()
&& name.length() <= 127;
}
// ensure every resource-table name passes utf8Safe before obfuscation Try / catch
try { ... } catch (AndrolibException e) { if (e.getMessage().contains("UTF-8 length is different")) { /* extract resource name from the log and fail with a rename hint */ } else throw e; } Prevention
- Keep resource and table names pure ASCII and short (<127 bytes).
- Run a pre-build lint that rejects non-ASCII resource identifiers.
- Enable AndResGuard obfuscation so original names are replaced before the writer runs.
- Review bundled library resources for non-ASCII names.
When it happens
Trigger: writeTableNameStringBlock with block.m_isUTF8 == true and a resource-table name whose UTF-8 byte length != name.length() (non-ASCII characters or length > byte range).
Common situations: Apps whose resource entries use localized/non-ASCII names, or libraries shipping resources with special characters in their names, being processed by AndResGuard.
Related errors
- writeSpecNameStringBlock
- writeSpecNameStringBlock
- writeTableNameStringBlock UTF-16LE length is different name
- Style data size is not multiple of 4
- writeSpecNameStringBlock styleOffsetCount != 0 …
AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12).
Data as JSON: /api/errors/3891d42764bcd256.
Report an issue: GitHub.
Appendix: source
Thrown at AndResGuard-core/src/main/java/com/tencent/mm/androlib/res/decoder/StringBlock.java:288
for (i = 0; i < stringCount; i++) {
stringOffsets[i] = offset;
//如果找不到即没混淆这一项,直接拷贝
if (tableProguardMap.get(i) == null) {
//需要区分是否是最后一项
int copyLen = (i == (stringCount - 1)) ? (block.m_strings.length - block.m_stringOffsets[i])
: (block.m_stringOffsets[i + 1] - block.m_stringOffsets[i]);
System.arraycopy(block.m_strings, block.m_stringOffsets[i], strings, offset, copyLen);
offset += copyLen;
totalSize += copyLen;
} else {
String name = tableProguardMap.get(i);
if (block.m_isUTF8) {
strings[offset++] = (byte) name.length();
strings[offset++] = (byte) name.length();
totalSize += 2;
byte[] tempByte = name.getBytes(Charset.forName("UTF-8"));
if (name.length() != tempByte.length) {
throw new AndrolibException(String.format(
"writeTableNameStringBlock UTF-8 length is different name %d, tempByte %d\n",
name.length(),
tempByte.length
));
}
System.arraycopy(tempByte, 0, strings, offset, tempByte.length);
offset += name.length();
strings[offset++] = NULL;
totalSize += name.length() + 1;
} else {
writeShort(strings, offset, (short) name.length());
offset += 2;
totalSize += 2;
byte[] tempByte = name.getBytes(Charset.forName("UTF-16LE"));
if ((name.length() * 2) != tempByte.length) {
throw new AndrolibException(String.format(
"writeTableNameStringBlock UTF-16LE length is different name %d, tempByte %d\n",
name.length(),View on GitHub (pinned to e4df245d82)