DocumentsPersonal
XML Parsing and Serialization
XML Parsing and Serialization
Type
Topic
Status
Published
Created
Jul 8, 2026
Updated
Jul 8, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

XML Parsing and Serialization in OpenDAL#

OpenDAL uses quick-xml as its XML engine for all storage backends that communicate over XML-based APIs. This includes S3-compatible services, Azure Blob/Files, Google Cloud Storage, Huawei OBS, WebDAV, and the oay gateway binary. The dependency is declared in core/Cargo.toml and bin/oay/Cargo.toml with the serialize and overlapped-lists features enabled.


Where quick-xml Is Used#

Service Backends (core crate)#

XML is used in two directions:

Deserialization (API responses → Rust structs): All S3-compatible backends — S3, OSS, COS, OBS — plus Azure Blob, Azure Files, and WebDAV use quick_xml::de::from_reader() or quick_xml::de::from_str() to parse list-objects, delete-objects, and error responses. GCS uses it for multipart upload initiation responses.

Serialization (Rust structs → XML request bodies): quick_xml::se::to_string() is called to build CompleteMultipartUploadRequest and DeleteObjectsRequest payloads for S3, OSS, COS, OBS, Azure Blob, and GCS .

Gateway (oay)#

The oay S3-frontend serializes ListBucketResult and error responses directly with quick_xml::se::to_string() .


Centralized Error Handling#

All XML errors feed through two helpers in core/src/raw/serde_util.rs:

Both are re-exported from core/src/raw/mod.rs and used uniformly via .map_err(new_xml_deserialize_error) chains across every XML-parsing service.

The S3 lister additionally marks deserialization errors as temporary, enabling automatic retries when a server returns incomplete XML under high load.


WebDAV Character Encoding Workaround#

The WebDAV backend's deserialize_multistatus() function applies a pre-processing step before deserializing PROPFIND responses: it percent-encodes a set of special characters (&()_+-=;) in the raw bytes before handing off to quick_xml::de::from_str(). The code comments this as HACKS! HACKS! HACKS! and references upstream tafia/quick-xml#719.


Security: RUSTSEC-2026-0195 (Memory Allocation DoS)#

quick-xml v0.41.0 (released 2026-06-29) addressed two security-relevant issues relevant to OpenDAL deployments:

  1. Memory allocation DoS via namespace flooding (#970): NamespaceResolver::push (used by every NsReader Start/Empty event) previously allocated one NamespaceBinding per xmlns / xmlns:* declaration with no upper bound. On a crafted M-byte start tag the resolver could allocate roughly 3×M bytes of heap before returning to the caller — enough to trigger out-of-memory conditions in servers with concurrent NsReader users. Fix: the default cap is now 256 declarations per element (DEFAULT_MAX_DECLARATIONS_PER_ELEMENT); excess declarations return NamespaceError::TooManyDeclarations. The limit is configurable via NamespaceResolver::set_max_declarations_per_element().

  2. O(N²) duplicate-attribute scan (#969): Attributes iterator previously performed an O(N²) scan for duplicate attributes on start tags with many attributes. v0.41.0 switches to a 64-bit hash pre-filter so the overall cost is O(N).

Advisory: RUSTSEC-2026-0195 tracks the namespace-binding vulnerability. As of 2026-07-08, OpenDAL's core and oay are still pinned to 0.37 ; a bump to ≥ 0.41.0 is required to remediate. A Dependabot PR (#7839) was opened to upgrade the Node.js bindings' quick-xml, and a separate bug report (#7885) tracks the upgrade for the core and oay crates.