{"record":{"id":"418c1c1327088afb","repo":"MuntashirAkon/AppManager","slug":"e-xml","errorCode":null,"errorMessage":"e","messagePattern":"e","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"libcore/compat/src/main/java/io/github/muntashirakon/compat/xml/Xml.java","lineNumber":117,"sourceCode":"     * <p>\n     * To ensure that both formats are detected and transparently handled\n     * correctly, you must shift to using both {@link #resolveSerializer} and\n     * {@code #resolvePullParser}.\n     */\n    public static @NonNull TypedXmlPullParser resolvePullParser(@NonNull InputStream in) throws IOException {\n        if (!in.markSupported()) {\n            in = new BufferedInputStream(in);\n        }\n        final TypedXmlPullParser xml;\n        if (isBinaryXml(in)) {\n            xml = newBinaryPullParser();\n        } else {\n            xml = newFastPullParser();\n        }\n        try {\n            xml.setInput(in, StandardCharsets.UTF_8.name());\n        } catch (XmlPullParserException e) {\n            throw new IOException(e);\n        }\n        return xml;\n    }\n\n    /**\n     * Creates a new {@link XmlSerializer} which is optimized for use inside the\n     * system, typically by supporting only a basic set of features.\n     * <p>\n     * In particular, the returned parser does not support namespaces, prefixes,\n     * properties, or options.\n     */\n    @SuppressWarnings(\"AndroidFrameworkEfficientXml\")\n    public static @NonNull TypedXmlSerializer newFastSerializer() {\n        return XmlUtils.makeTyped(new FastXmlSerializer());\n    }\n\n    /**\n     * Creates a new {@link XmlSerializer} that writes XML documents using a","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/compat/src/main/java/io/github/muntashirakon/compat/xml/Xml.java#L99-L135","documentation":"resolvePullParser() attaches the input stream to a fast XmlPullParser and calls setInput(in, \"UTF-8\"), which parses the initial document prolog immediately. If the stream does not contain well-formed XML text, the parser throws XmlPullParserException, which is translated to an IOException so callers only need to handle IOException. This means the data was not parseable XML text at all (as opposed to Android binary XML, which is detected beforehand by isBinaryXml).","triggerScenarios":"Passing a non-XML stream to Xml.resolvePullParser(): a raw binary file that is not AXML (e.g. PNG, DEX), a truncated XML document cut off before the root tag, or text with an invalid encoding/byte-order mark that fails UTF-8 prolog parsing.","commonSituations":"Extracting an APK entry with the wrong path and getting a different resource file; downloading a manifest over a broken connection and receiving an HTML error page; unzipping with an incorrect offset producing garbage bytes.","solutions":["Dump the first bytes of the stream and confirm they start with an XML prolog ('<?xml' or '<') before parsing.","Check for Android binary XML first (0x03 0x00 0x08 0x00 magic) via Xml.isBinaryXml and use an AXML-capable parser if it matches.","Verify you extracted the correct file entry and that it is complete (compare sizes/hashes with the source archive).","Catch IOException around resolvePullParser and log the first 64 bytes of input to identify what was actually passed in."],"exampleFix":"// before\nXmlResourceParser p = Xml.resolvePullParser(stream);\n// after\nstream.mark(8);\nbyte[] head = new byte[4];\nint n = stream.read(head);\nstream.reset();\nif (n == 4 && head[0] == 0x03 && head[1] == 0x00) {\n    throw new IOException(\"Binary XML (AXML) detected; use a binary XML parser\");\n}\nXmlResourceParser p = Xml.resolvePullParser(stream);","handlingStrategy":"try-catch","validationCode":"in.mark(8); byte[] h = new byte[4]; int n = in.read(h); in.reset();\nif (n < 4) throw new IOException(\"Input too short to be XML\");\nif (h[0] == 0x03 && h[1] == 0x00) throw new IOException(\"Binary AXML, not text XML\");\nif (h[0] != '<' && !(h[0] == (byte)0xEF)) throw new IOException(\"Input does not look like XML text\");","typeGuard":null,"tryCatchPattern":"try {\n    XmlResourceParser p = Xml.resolvePullParser(in);\n} catch (IOException e) {\n    // input was not well-formed XML text\n    log.warn(\"XML parse failed: \" + e.getMessage());\n}","preventionTips":["Always sniff the first bytes and route binary AXML to a binary parser before calling resolvePullParser.","Verify archive extraction paths so the intended entry is passed to the parser.","Check completeness (size/hash) of files produced by downloads or unzipping."],"tags":["xml","parsing","encoding","android"],"backgroundTag":"xml-parse-error","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"}