Sitelet https://github.com/flutter/packages/pull/12479
Skip to content

[cross_file] fixed readAsString decoding in-memory bytes as UTF-16 - #12479

Merged
auto-submit[bot] merged 2 commits into
flutter:mainfrom
glitchfl:fix-cross-file-utf8-read-as-string
Aug 25, 2026
Merged

auto-submit[bot] merged 2 commits into
flutter:mainfrom
glitchfl:fix-cross-file-utf8-read-as-string

Conversation

@glitchfl

Copy link
Copy Markdown
Contributor

XFile.fromData(utf8.encode('😀')).readAsString() hands back mojibake

The bytes branch uses String.fromCharCodes which just widens each byte into
its own UTF-16 code unit so anything outside ASCII comes out mangled and the
encoding parameter the method accepts never gets used at all. The file-backed
branch right below it passes encoding through fine, and web already does
readAsBytes().then(encoding.decode) so this is mostly just making native do
what web has been doing all along.

I made the method async while I was in there and that bit is deliberate
rather than cosmetic: encoding.decode can throw on bad input where
fromCharCodes never could and without async that would come out
synchronously instead of as a failed future, which isn't what you get from
either the web version or the _file.readAsString path.

fixes flutter/flutter#165120

AI usgae: I used antigravity (with gemini 3.7 flash)

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the readAsString method in XFile to decode bytes using the provided encoding instead of String.fromCharCodes, fixing an issue where multi-byte characters were incorrectly decoded. It also adds corresponding unit tests for multi-byte characters, non-default encodings, and malformed data. The reviewer suggested avoiding the async keyword in readAsString to prevent unnecessary microtask delays and overhead, recommending the use of Future.sync instead.

Comment thread packages/cross_file/lib/src/types/io.dart Outdated
@glitchfl
glitchfl force-pushed the fix-cross-file-utf8-read-as-string branch from 8c83c4b to c49b2dc Compare August 16, 2026 14:40

@bparrishMines bparrishMines left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bparrishMines

Copy link
Copy Markdown
Contributor

@stuartmorgan-g or @tarrinneal for secondary review

@stuartmorgan-g stuartmorgan-g added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 25, 2026
@auto-submit
auto-submit Bot merged commit 40f0b93 into flutter:main Aug 25, 2026
14 checks passed
zijiehe-google-com pushed a commit to zijiehe-google-com/flutter that referenced this pull request Aug 25, 2026
…er#191734)

flutter/packages@df2ba94...740f093

2026-08-25 srawlins@google.com [cupertino_ui] Remove unused parameters
from constructors of generic classes. (flutter/packages#12457)
2026-08-25 srawlins@google.com [material_ui] Remove unused parameters
from constructors of generic classes. (flutter/packages#12458)
2026-08-25 6655696+guidezpl@users.noreply.github.com Ignore shared code
for iOS platform implementation of Google Maps plugin
(flutter/packages#12529)
2026-08-25 136096126+glitchfl@users.noreply.github.com [cross_file]
fixed `readAsString` decoding in-memory bytes as UTF-16
(flutter/packages#12479)
2026-08-25 lozhkovoi@gmail.com [cupertino_ui] Remove two items assert to
allow CupertinoTabBar to have one tab (flutter/packages#12546)
2026-08-25 huahua8893@sina.cn [cupertino_ui] Fix covered sheet revealing
root route through top gap (flutter/packages#12530)
2026-08-25 fluttergithubbot@gmail.com Sync release-go_router-18.0.0 to
main (flutter/packages#12575)
2026-08-25 fluttergithubbot@gmail.com Sync release-material_ui-1.1.0 to
main (flutter/packages#12577)
2026-08-25 fluttergithubbot@gmail.com Sync release-cupertino_ui-1.0.1 to
main (flutter/packages#12576)
2026-08-24 41930132+hellohuanlin@users.noreply.github.com
[quick_actions_ios]unskip XCUITests (flutter/packages#12436)
2026-08-24 karthimanikuttan001@gmail.com Fix RangeSlider thumb overlay
remains visible after touch interaction ends (flutter/packages#12560)
2026-08-24 victor.orozco@cloudsufi.com [google_sign_in] Increase iOS
coverage tests (flutter/packages#12484)
2026-08-24 269567208+reidbaker-agent@users.noreply.github.com
[camera_android_camerax] Migrate from dart_skills_lint to skills_lint
(flutter/packages#12543)
2026-08-24 74037732+developerashkan@users.noreply.github.com [go_router]
Clarify onEnter/redirect ordering, add regression test
(flutter/packages#12337)
2026-08-24 brunocorona.alcantar@gmail.com [material_ui] Port
flutter/flutter flutter#185149 "Slider label clips the screen"
(flutter/packages#12572)
2026-08-24 engine-flutter-autoroll@skia.org Roll Flutter from
65c9a8d to 9a82789 (17 revisions) (flutter/packages#12578)
2026-08-24 stuartmorgan@google.com [tool] Fix dart_test.yaml parsing
(flutter/packages#12574)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC flutter-ecosystem@google.com on the revert to ensure that a
human
is aware of the problem.

To file a bug in Flutter:
https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
danielleon-cmd pushed a commit to victogomez-cs/packages-fork that referenced this pull request Aug 27, 2026
…lutter#12479)

`XFile.fromData(utf8.encode('😀')).readAsString()` hands back mojibake

The bytes branch uses `String.fromCharCodes` which just widens each byte into
its own UTF-16 code unit so anything outside ASCII comes out mangled and the
`encoding` parameter the method accepts never gets used at all. The file-backed
branch right below it passes `encoding` through fine, and web already does
`readAsBytes().then(encoding.decode)` so this is mostly just making native do
what web has been doing all along.

I made the method `async` while I was in there and that bit is deliberate
rather than cosmetic: `encoding.decode` can throw on bad input where
`fromCharCodes` never could and without `async` that would come out
synchronously instead of as a failed future, which isn't what you get from
either the web version or the `_file.readAsString` path.

fixes flutter/flutter#165120

AI usgae: I used antigravity (with gemini 3.7 flash)
jagadeesh8682 pushed a commit to jagadeesh8682/packages that referenced this pull request Sep 2, 2026
…lutter#12479)

`XFile.fromData(utf8.encode('😀')).readAsString()` hands back mojibake

The bytes branch uses `String.fromCharCodes` which just widens each byte into
its own UTF-16 code unit so anything outside ASCII comes out mangled and the
`encoding` parameter the method accepts never gets used at all. The file-backed
branch right below it passes `encoding` through fine, and web already does
`readAsBytes().then(encoding.decode)` so this is mostly just making native do
what web has been doing all along.

I made the method `async` while I was in there and that bit is deliberate
rather than cosmetic: `encoding.decode` can throw on bad input where
`fromCharCodes` never could and without `async` that would come out
synchronously instead of as a failed future, which isn't what you get from
either the web version or the `_file.readAsString` path.

fixes flutter/flutter#165120

AI usgae: I used antigravity (with gemini 3.7 flash)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD p: cross_file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[cross_file] readAsString assumes bytes are UTF-16

3 participants