{"record":{"id":"5d4445dd927d026c","repo":"MuntashirAkon/AppManager","slug":"e-getmessage","errorCode":null,"errorMessage":"e.getMessage()","messagePattern":"e\\.getMessage\\(\\)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libcore/compat/src/main/java/io/github/muntashirakon/compat/xml/Xml.java","lineNumber":50,"sourceCode":"    static {\n        boolean useAbx;\n        try {\n            useAbx = (boolean) Objects.requireNonNull(Class.forName(\"android.os.SystemProperties\")\n                    .getDeclaredMethod(\"getBoolean\", String.class, boolean.class)\n                    .invoke(null, \"persist.sys.binary_xml\", Build.VERSION.SDK_INT >= Build.VERSION_CODES.S));\n        } catch (Exception ignore) {\n            useAbx = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;\n        }\n        ENABLE_BINARY_DEFAULT = useAbx;\n    }\n\n    public static boolean isBinaryXml(@NonNull InputStream in) throws IOException {\n        final byte[] magic = new byte[4];\n        if (in instanceof FileInputStream) {\n            try {\n                Os.pread(((FileInputStream) in).getFD(), magic, 0, magic.length, 0);\n            } catch (ErrnoException e) {\n                throw new IOException(e.getMessage(), e);\n            }\n        } else {\n            if (!in.markSupported()) {\n                in = new BufferedInputStream(in);\n            }\n            in.mark(8);\n            in.read(magic);\n            in.reset();\n        }\n        return Arrays.equals(magic, BinaryXmlSerializer.PROTOCOL_MAGIC_VERSION_0);\n    }\n\n    public static boolean isBinaryXml(@NonNull ByteBuffer buffer) {\n        final byte[] magic = new byte[4];\n        buffer.mark();\n        buffer.get(magic);\n        buffer.reset();\n        return Arrays.equals(magic, BinaryXmlSerializer.PROTOCOL_MAGIC_VERSION_0);","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/compat/src/main/java/io/github/muntashirakon/compat/xml/Xml.java#L32-L68","documentation":"Xml.isBinaryXml() peeks the first 4 bytes of the stream to detect Android binary XML (AXML). When the stream is a FileInputStream it reads via Os.pread on the underlying file descriptor, and an ErrnoException from the kernel (bad fd, I/O error, permission) is rethrown as an IOException carrying the errno message. It signals that the file could not be read at the OS level, not that the XML is malformed.","triggerScenarios":"Calling Xml.resolvePullParser() (which calls isBinaryXml) on a FileInputStream whose descriptor cannot be pread: closed FD, file deleted between open and read, EIO on a damaged filesystem, or a special file (pipe/device) that doesn't support positional reads.","commonSituations":"Parsing an APK entry extracted to a temp file that was deleted before parsing; opening a path obtained from another process whose FD was closed; storage corruption on SD card or /proc-style pseudo-files passed in directly.","solutions":["Verify the file exists and is readable before opening: File.canRead() and length() >= 0.","Ensure the FileInputStream is opened by the caller and not closed or reused after a previous parse; open a fresh stream per parse.","If pread keeps failing, wrap the stream yourself in a BufferedInputStream so isBinaryXml takes the mark/reset path instead of the FD path.","Catch IOException around resolvePullParser and surface the file path plus the errno message to diagnose the storage-level problem."],"exampleFix":"// before\nInputStream in = new FileInputStream(f);\nXmlResourceParser p = Xml.resolvePullParser(in); // may throw IOException: pread errno\n// after\nFile f = new File(path);\nif (!f.canRead()) throw new IOException(\"Cannot read \" + path);\nInputStream in = new BufferedInputStream(new FileInputStream(f)); // avoids FD pread path\nXmlResourceParser p = Xml.resolvePullParser(in);","handlingStrategy":"try-catch","validationCode":"if (!file.canRead() || file.length() < 4) throw new IOException(\"File missing or too small: \" + file);","typeGuard":null,"tryCatchPattern":"try {\n    XmlResourceParser p = Xml.resolvePullParser(in);\n} catch (IOException e) {\n    throw new IOException(\"Cannot read XML source: \" + e.getMessage(), e);\n}","preventionTips":["Open a fresh FileInputStream for each parse and never close it before parsing finishes.","Check File.canRead()/length() before parsing.","Wrap non-file streams in BufferedInputStream so the FD pread path is skipped."],"tags":["io","android","xml","file-descriptor"],"backgroundTag":"file-read-failed","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}