{"record":{"id":"cf80baf0b7589e73","repo":"shwenzhang/AndResGuard","slug":"unsupportedoperationexception","errorCode":null,"errorMessage":"UnsupportedOperationException","messagePattern":"UnsupportedOperationException","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"AndResGuard-core/src/main/java/com/tencent/mm/directory/ZipRODirectory.java","lineNumber":65,"sourceCode":"  public ZipRODirectory(File zipFile, String path) throws DirectoryException {\n    super();\n    try {\n      mZipFile = new ZipFile(zipFile);\n    } catch (IOException e) {\n      throw new DirectoryException(e);\n    }\n    mPath = path;\n  }\n\n  public ZipRODirectory(ZipFile zipFile, String path) {\n    super();\n    mZipFile = zipFile;\n    mPath = path;\n  }\n\n  @Override\n  protected AbstractDirectory createDirLocal(String name) throws DirectoryException {\n    throw new UnsupportedOperationException();\n  }\n\n  @Override\n  protected InputStream getFileInputLocal(String name) throws DirectoryException {\n    try {\n      return getZipFile().getInputStream(new ZipEntry(getPath() + name));\n    } catch (IOException e) {\n      throw new PathNotExist(name, e);\n    }\n  }\n\n  @Override\n  protected OutputStream getFileOutputLocal(String name) throws DirectoryException {\n    throw new UnsupportedOperationException();\n  }\n\n  @Override\n  protected void loadDirs() {","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/shwenzhang/AndResGuard/blob/e4df245d82f27d9a2d0dd108260a3510cbaba849/AndResGuard-core/src/main/java/com/tencent/mm/directory/ZipRODirectory.java#L47-L83","documentation":"ZipRODirectory is read-only; createDirLocal unconditionally throws UnsupportedOperationException. Any mutation path that reaches createDir on a ZipRODirectory (including createDir/getFileOutput in AbstractDirectory) fails because zip-backed trees cannot create new entries in place.","triggerScenarios":"Calling createDir(path) or getFileOutput on a ZipRODirectory obtained from an APK/zip, e.g. trying to add new resource folders directly inside the archive.","commonSituations":"Attempting to write obfuscated resources back into the source APK; copying a write-flow built on FileDirectory to a zip-backed Directory without changing types.","solutions":["Extract the zip into a real folder (new FileDirectory(unpackedDir)) and perform all mutations there.","Only use read APIs (getFileInput, containsFile, listEntries) on ZipRODirectory instances.","Wrap createDir in try-catch UnsupportedOperationException if your code must handle both read-only and writable directories."],"exampleFix":"// before\nDirectory dir = new ZipRODirectory(apkFile, \"\");\nDirectory out = dir.createDir(\"new/res\"); // UnsupportedOperationException\n// after\nFile unpacked = new File(\"build/apk-unpacked\");\nunpacked.mkdirs();\nDirectory dir = new FileDirectory(unpacked);\nDirectory out = dir.createDir(\"new/res\");","handlingStrategy":"try-catch","validationCode":"if (dir instanceof ZipRODirectory) { /* use read-only APIs or unpack to FileDirectory first */ }","typeGuard":"boolean isWritableDirectory(AbstractDirectory d) { return d instanceof FileDirectory; }","tryCatchPattern":"try { return dir.createDir(path); } catch (UnsupportedOperationException e) { return unpackAndCreate(dir, path); }","preventionTips":["Treat ZipRODirectory as strictly read-only in your code","Unpack archives to a FileDirectory before any mutation","Write tests covering both directory implementations if you support both"],"tags":["read-only","unsupported","zip"],"backgroundTag":"unsupported-operation","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"}