Privacy and data boundary

Define an HTML Text Projection for Android File Imports

Specify a bounded text projection for user-selected HTML with a pinned parse-only entry point, charset, inclusion policy, and no accidental WebView or network-fetch assumptions.

Review status: Fact and editorial QA complete; owner review pending · 2026-10-08 · Fact IDs: ANDROID-HTML-DOCUMENT-EXTRACTION-2026-10, RAG-01, ANDROID-PRIVACY-01

Direct answer

Treat a selected HTML file as untrusted source data, not as a page to open in a browser. A parser can build a tree without reproducing browser layout, CSS, JavaScript, accessibility behavior, or article semantics. Decide whether the product wants document text, an article-like subset, link labels, table cells, image alternatives, or another named projection. A parser returning a Document does not decide which text is relevant, user-visible, or appropriate for a model prompt. Keep source bytes, decoded text, parsed tree, projection, and model input as separate stages with separate outcomes. Define how bytes become characters before extraction. Use the selected provider stream and an explicit supported charset policy; test BOM, declared meta charset, absent charset, conflicting labels, malformed byte sequences, and read errors with the exact parser API. Do not assume every file is UTF-8 or silently replace invalid sequences and then call the projection exact. Record the declared/detected encoding and fallback decision. Preserve the original document and a stable source identity so the user can compare extracted text against the file that was selected. Choose a parser deliberately and use its supplied-data entry point. The WHATWG HTML Standard describes browser DOMParser: script elements are not evaluated during parseFromString, but dangerous nodes or attributes are not sanitized. This browser API is not an Android platform import API, and inactive scripting alone does not establish a resource handler has made no requests. With jsoup, use the exact parse(String, baseUri) or parse(InputStream, charset, baseUri) overload for supplied data. connect(url) creates a Connection; execution through get, post, or execute performs the fetch. The parse(URL, timeoutMillis) overload also fetches a URL, so the method name parse is not an offline guarantee. Pin and test the actual overload and parser build. Base URI is metadata for resolving relative references, not permission to open them. A selected content URI grant authorizes access to the chosen source according to the picker/provider contract; an HTML base URL does not extend that grant or authorize fetching images, frames, stylesheets, scripts, or links. Keep a document original locator separate from any synthetic parser base URI. If relative links are retained for a preview, store them as inert references and require a separate explicit feature before resolving or opening them. A parser test should fail if it unexpectedly invokes a network or resource resolver. Define a text projection instead of claiming visible text without a rendering engine. One profile may traverse body headings, paragraphs, list items, table captions/cells, and anchor labels in document order. It may exclude head, navigation/sidebar chrome, script, style, template, form-control values, and nodes marked hidden or aria-hidden=true by policy; header/footer/aside content needs an explicit rule because it can be navigation or user-authored material. Image alt text can be a separately labeled field, not silently blended into prose. A static parser cannot generally determine computed CSS visibility or what assistive technology announced, so record those unknowns rather than pretending the result matches a browser screenshot or accessibility tree. Prevent user content from escaping its intended stage. Do not load the selected local file into WebView as an extraction shortcut, and do not concatenate parsed markup into a new HTML page. WebView file access and script settings can expose app-readable files when untrusted content is loaded. Render the approved projection as plain text or through a separately reviewed renderer; preserve link targets as references, never execute script, event handlers, forms, meta refresh, or embedded objects. External resources are not needed to extract static text and should remain unfetched by default. Bound work at the stream and tree layers, but distinguish when each bound takes effect. Enforce a real byte or decoder limit before buffering/parsing. A node-count or depth check that requires a completed tree is only post-parse acceptance: it can reject an oversized tree but cannot promise that tree allocation was bounded. Use parser-native preallocation controls only when the chosen parser documents them; otherwise isolate the parse and state the limitation. Cancellation notification is not proof that a blocking parse stopped. Give each selection an owner/revision token, check it when applying results in the same serialized or atomic event path, and close streams or remove derived copies only after the parser has actually exited. Keep the source immutable. A tolerant parser may repair malformed markup; report that recovery and scope the projection to parser/version rather than calling it browser-equivalent. Test a synthetic corpus with source hashes and independently expected projections: malformed but recoverable markup, UTF-8 BOM, alternate supported charset, conflicting charset signals, script/style/template blocks, hidden attributes, aria-hidden nodes, forms with secret-like values, tables, link labels with external hrefs, image alt text, base elements, nested lists, comments, and oversized input. Instrument network and resolver hooks around the parser; test the exact parse API separately from connect/fetch APIs. Compare text inclusion, order, whitespace normalization, omissions, and any link references. This method does not claim Cove supports HTML import or that a static projection equals what a browser displays.

A local report contains a hidden token and external image links

A user selects an HTML export containing a report table, a form with a previously entered access token, a script block, aria-hidden annotations, a relative base element, and remote image URLs. The team wants a local summary but must not open a browser or include private form state by accident.

Decision

Decode with a pinned parser and explicit charset, build a declared body-text projection with form/hidden policy, preserve link references without fetching, and show the exact projection before processing.

Expected outcome

The local task consumes only the reviewed projection. The source stays unchanged, excluded fields remain excluded, and no claim is made about full browser-visible or accessible content.

Evidence to collect

The claim becomes reviewable only when the following evidence is attached to the same artifact and test run:

  • Selected source identity and charset decision
  • Parser overload and bounded post-parse traversal
  • Included/excluded node fixtures and external-resource canaries

A privacy claim needs a data inventory and traffic evidence. A local-model label by itself is not proof.

Implementation workflow

  1. Select and identify the source file. Use a user-selected document URI, retain the returned access grant and source revision, and stream bytes through an explicit size limit. Never substitute a raw local path or open the file in WebView for extraction.
  2. Choose charset and parser version. Name supported charset signals and conflict behavior, then pin the exact String/InputStream parse overload and parser artifact/version. Exclude parse(URL, timeoutMillis) and Connection execution; connect(url) creates that Connection but does not fetch until executed.
  3. Write the projection inclusion policy. Specify included body structures, heading/list/table order, anchor labels, optional image alt text, and exclusions for script/style/template/forms/hidden markers. State that CSS visibility and browser accessibility are not inferred.
  4. Keep references inert and processing bounded. Preserve base URI and hrefs as data only; do not fetch them. Enforce byte/decoder limits before parsing. Treat tree depth/node checks as post-parse rejection unless the exact parser documents an earlier control; isolate parsing if preallocation cannot be bounded.
  5. Review and test the derived text. Show the normalized projection and omissions before model input. Test malformed, encoded, hidden, form, table, base/relative-link, resource-canary, oversized, and cancellation cases. A cancellation signal alone does not stop a blocked parser: guard result application with the current owner/revision in the same serialized or atomic path, and close the input only after parsing exits; keep the source unchanged.

Keep each transition observable. A failure should identify the stage, artifact, runtime, and recovery action without logging private user content.

Acceptance criteria

  • The selected source URI/grant, raw bytes, decoded text, parser tree, and derived projection remain separate and attributable.
  • Charset conflicts and malformed bytes have explicit outcomes; parser/version and tolerant-repair behavior are recorded.
  • Inclusion/exclusion policy covers body structure, hidden/form/script/style content, links, alt text, and unknown CSS/accessibility visibility.
  • Base URI and href values do not grant access or trigger fetch; only the parse-only API runs, verified with network/resource canaries. Byte/decoder caps act before parse, while tree-only depth/node checks are labeled post-parse acceptance unless the selected parser documents pre-parse enforcement.
  • WebView is not used as an extraction shortcut; no full-browser-visible, accessibility-equivalent, or Cove-support claim is made.

Decision table

DimensionChoice or evidenceHow to interpret it
HTML parse-only text projectionParse a selected source in memory and apply a named structural inclusion profile.Creates derived text without browser layout; the profile does not automatically identify all visible or relevant content.
WebView renderingDo not use for extraction of untrusted local HTML.Loads content in a browser component whose file, script, and resource settings create a different security boundary.
XML DTD ingestionConfigure the exact XML parser for declarations/entities and limits.XML parser controls do not define HTML tree construction or its malformed-markup recovery.
EML HTML MIME alternativeFirst select/decode the email MIME part, then invoke a separate HTML projection policy.MIME transfer encoding and charset select source bytes; they do not define HTML text inclusion.

Failure patterns to prevent

  • Using jsoup URL overloads as an offline parser
  • Treating DOMParser as sanitizer or a no-network proof
  • Treating base URI as file permission

Also prevent silent fallback, unpinned artifacts, missing cancellation, and conclusions that combine unlike configurations. Store unsuccessful runs alongside successful ones.

Minimum reproducibility record

LayerRecord
DeviceManufacturer, model, chipset, RAM class, operating-system build
SoftwareApplication version and git commit
ModelFamily, variant, revision, format, file length, hash, quantization
RuntimeName, revision, requested backend, observed backend evidence
WorkloadFixture revision, input hash, prompt hash, output policy
OutcomeCompleted, failed, cancelled, fallback, and privacy-safe diagnostics

Release checklist

  • ☐ The primary query is answered without an unsupported number.
  • ☐ Every artifact and runtime is pinned.
  • ☐ The representative task and failure policy are explicit.
  • ☐ Lifecycle, cancellation, cleanup, and fallback are tested.
  • ☐ User-content and network boundaries are documented.
  • ☐ Result wording applies only to the recorded configuration.
  • ☐ The page links to raw method or evidence when results are added.

Sources and related evidence

Chinese deployment and troubleshooting content is organized in the .奇连 AI 端侧专题.

Frequently asked questions

Does DOMParser make HTML safe because scripts do not run during parsing?

No. The HTML Standard says script elements are not evaluated in the parsed document, but parseFromString does not sanitize dangerous nodes or attributes, and that browser API does not establish Android resource-handler behavior.

Does a base URI authorize fetching relative images or links?

No. It is reference-resolution metadata, not permission. Keep relative links inert and do not fetch resources unless a separate feature and user choice authorize that operation.

Does a post-parse node limit bound parser memory?

No. If the node count is available only after a tree is built, it can reject that result but does not bound allocations already made. Enforce byte/decoder caps before parsing and use documented parser-native pre-parse controls or isolation where needed.

Does cancellation mean a blocking parse has stopped?

Not by itself. Apply results only if the selection owner/revision is still current in the same serialized or atomic path; close the stream or delete derived data after the parser has actually exited, and never mutate the source.

Can a static parser tell which text was visible in the browser?

Not in general. CSS layout, scripting, viewport, and accessibility behavior can change what is visible or announced. Name the projection rules and report those rendering-dependent facts as unknown.

Does any jsoup.parse overload guarantee a supplied-data-only operation?

No. String/InputStream overloads parse supplied data, but parse(URL, timeoutMillis) fetches a URL. connect(url) creates a Connection that fetches when get, post, or execute runs. Pin and test the exact overload, input stream origin, and resource boundary rather than trusting a method name.