shwenzhang/AndResGuard · error · AndrolibException
writeSpecNameStringBlock styleOffsetCount != 0 …
Error message
writeSpecNameStringBlock styleOffsetCount != 0 styleOffsetCount %d
What it means
writeSpecNameStringBlock re-reads the resource-table string pool while writing out a stripped spec-name block, and it only supports pools with no style spans. If styleOffsetCount (the style-offset array length in the chunk header) is non-zero, the writer cannot represent the styles and throws AndrolibException.
Solutions
- Remove or simplify styled (spanned) strings from resource tables so the string pool has no styles.
- Use a newer AndResGuard version that may handle style sections, or patch StringBlock to copy the styles section verbatim.
- As a workaround, pre-process the arsc with androidwide tooling (aapt2) to strip spans before obfuscation.
- If the styled strings are only in resources.arsc (not needed at runtime), rebuild resources without formatting spans.
Defensive patterns
Strategy: validation
Validate before calling
// Inspect the string pool header before writing
int styleOffsetCount = readIntAt(chunkStart + 20);
if (styleOffsetCount != 0) {
// skip the spec-name fast path or strip styles first
} Try / catch
try { block.writeSpecNameStringBlock(...); } catch (AndrolibException e) { if (e.getMessage().contains("styleOffsetCount != 0")) { /* fall back to full (non-stripped) write path */ } else throw e; } Prevention
- Avoid styled/spanned strings in resource tables when using AndResGuard.
- Run resource shrinking so styled strings are minimized before this stage.
- Test obfuscation on a copy of the APK before release builds.
- Keep AndResGuard updated for style-section handling improvements.
When it happens
Trigger: Calling writeSpecNameStringBlock on a resources.arsc string pool whose header declares styleOffsetCount != 0 (the chunk contains styled strings/span info).
Common situations: Running AndResGuard over APKs that contain styled strings in the resource table (HTML-like <b>/<i> spans in resource strings), typically from apps with rich text resources.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Style data size is not multiple of 4
- writeSpecNameStringBlock
- writeSpecNameStringBlock
- writeTableNameStringBlock UTF-8 length is different name
- writeTableNameStringBlock UTF-16LE length is different name
AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12).
Data as JSON: /api/errors/74666f248693e6ea.
Report an issue: GitHub.
Appendix: source
Thrown at AndResGuard-core/src/main/java/com/tencent/mm/androlib/res/decoder/StringBlock.java:115
int size = (chunkSize - stylesOffset);
if ((size % 4) != 0) {
throw new IOException("Style data size is not multiple of 4 (" + size + ").");
}
block.m_styles = reader.readIntArray(size / 4);
}
return block;
}
public static int writeSpecNameStringBlock(
ExtDataInput reader, ExtDataOutput out, Map<String, Set<String>> specNames, Map<String, Integer> curSpecNameToPos)
throws IOException, AndrolibException {
int type = reader.readInt();
int chunkSize = reader.readInt();
int stringCount = reader.readInt();
int styleOffsetCount = reader.readInt();
if (styleOffsetCount != 0) {
throw new AndrolibException(String.format("writeSpecNameStringBlock styleOffsetCount != 0 styleOffsetCount %d",
styleOffsetCount
));
}
int flags = reader.readInt();
boolean isUTF8 = (flags & UTF8_FLAG) != 0;
int stringsOffset = reader.readInt();
int stylesOffset = reader.readInt();
reader.readIntArray(stringCount);
int size = ((stylesOffset == 0) ? chunkSize : stylesOffset) - stringsOffset;
if ((size % 4) != 0) {
throw new IOException("String data size is not multiple of 4 (" + size + ").");
}
byte[] temp_strings = new byte[size];
reader.readFully(temp_strings);
int totalSize = 0;
out.writeCheckInt(type, CHUNK_STRINGPOOL_TYPE);View on GitHub (pinned to e4df245d82)