UI5 / UI5/cli

Chromium 153+: UTF-8 BOM kept by `@ui5/builder` in bundles breaks apps

Open
#1,601 1 comment 0 reactions 1 assignee View on GitHub

@flovogt is already working on this.

Since Sep 18, 2026.

module/ui5-builder
Dominant language
JavaScript
Stars
511
Forks
83
Avg merge
1d 5h
Merged PRs (30d)
55

Description

Expected Behavior

When an XML view/fragment file that was accidentally saved as "UTF-8 with BOM" is bundled (e.g. as Component-preload.js), the resulting inlined string should be parseable, especially for strict XML engines like the Rust-based one being used more by Chromium 153+. A leading Byte Order Mark (EF BB BF / U+FEFF / zero width no-break space) in the source file should not end up as a character inside the bundle.

Current Behavior

The builder decodes the resource with (await resource.buffer()).toString() at:

https://github.com/UI5/cli/blob/135076c50e3ebac6d8d8a72cdad18da14846d573/packages/builder/lib/lbt/bundle/Builder.js#L505-L516

The above line preserves a leading BOM as a U+FEFF character and then emits it via makeStringLiteral that currently escapes only ', \r, \n, \t, and \\.

The resulting preload entry looks like ...:

"my/app/view/App.view.xml":'\uFEFF<mvc:View ...>...</mvc:View>'

... where the BOM (\uFEFF, DevTools might show it differently) now sits between the opening ' and the <.

Chromium has a new internal XML engine used by the DOMParser (which SAPUI5 uses e.g. in sap/ui/util/XMLHelper.parse), that is based on Rust and memory-safe. With Chromium 153, that new Rust-based XML engine has become the default for specific scenarios according to the release note page for Chrome 153 section "XML parsing in Rust for non-XSLT scenarios":

To improve browser security and protect users against memory-related vulnerabilities, Chrome 153 updates its XML parsing engine to a memory-safe Rust implementation for several common scenarios. [...] The new, safer parser handles the following scenarios [...]:

  • DOMParser Web API
  • Accessing responseXML of XMLHttpRequest
  • ...

Earlier Chromium versions used the previous engine by default which happened to tolerate BOM-characters that the new XML engine now rejects. The new engine existed already in Chromium 152 but was off by default. The app also works when the bundle is not used (e.g. with the URL parameter sap-ui-xx-componentPreload=off) despite having been saved with BOM.

Steps to Reproduce the Issue

  1. Using the UI5/sample-app, save webapp/view/App.view.xml as "UTF-8 with BOM" (e.g. via VSCode's "Save with Encoding").

  2. npm install && npm run build && npm run serve-dist and open the app in Chrome/Edge 153+ which should show the failure.

    If the issue is still not reproducible: navigate to about://version/?show-variations-cmd and see whether it reports either XMLRustForNonXslt inside --disable-features=... or XMLParsingRustNonXsltKillSwitch_.../Disabled... under --force-fieldtrials. If so, try a different Chromium browser (e.g. Edge 153+). If still not reproducible, or alternatively, use Chrome for Testing:

    npx @puppeteer/browsers install chrome@153.0.8010.47 && npx @puppeteer/browsers launch chrome@153.0.8010.47
    

    You could also append -- --enable-features=XMLRustForNonXslt --disable-field-trial-config to the above launch command (-- is required) to be sure, but should not be needed.


[!Note]
While the above issue describes the Chromium 153+ scenario, a *.properties file saved as "UTF-8 with BOM" doesn't crash but silently corrupts its first i18n key. The .properties branch runs escapePropertiesFile --> nonAsciiEscaper, which escapes every non-ASCII char, turning the leading U+FEFF into the literal escape sequence \uFEFF at the very start of the bundled string. At runtime, the resource-bundle parser (sap/base/util/Properties.js) splits lines with rLines = /(?:\r\n|\r|\n|^)[ \t\f]*/ and decodes \uFEFF back to the character while reading the key. The first key therefore becomes \uFEFFTITLE=... instead of TITLE=..., so that one translation fails to resolve with no error in the console while the user sees only the key "TITLE" in the UI.

Unlike the XML case, this *.properties case is browser-independent.


Given App.view.xml and i18n.properties saved with BOM:

Image

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.