[GH-ISSUE #7226] [Bug] identify_flutter_build reports dart_version null on release engines #4306

Closed
opened 2026-10-31 00:48:46 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @JayOfTheKeyboard on GitHub (Oct 26, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/7226

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Native analysis or decompilation

Observed behavior

identify_flutter_build returns dart_version: null for every real Flutter engine I checked, including the Flutter Gallery 2.9.2 APK that verify:flutter pins. The engines do carry their Dart version, without the Dart VM version: label the scanner waits for.

Reproduction

  1. npm run verify:flutter -- --apk flutter_gallery_Android.apk --expectations scripts/fixtures/flutter-gallery-expectations.json on main, or rea identify-flutter-build on any release APK.
  2. Read dart_version for each ABI: null.
  3. strings -a lib/arm64-v8a/libflutter.so | grep -E '^[0-9]+\.[0-9]+\.[0-9]+.* \((stable|beta|dev)\)' shows the version string.

Reproduces every time, on six engines (three ABIs each from two APKs).

Expected behavior

dart_version reports the Dart version string the engine embeds, e.g. 3.7.2 (stable) (Tue Mar 11 04:27:50 2025 -0700) on "android_arm64".

Impact and scope

The field is null on all release engines I could check, so callers never get the Dart version from a real APK. docs/flutter-analysis.md says "Release engine builds often strip the Dart VM version string", but the version is present, just unlabeled. No effect on other fields.

REA version

main e54bf1006 (6.8.0)

Runtime and platform

Node.js 24.22.1, Fedora 44, x86_64

Target and artifact context

Android APKs, libflutter.so for arm64-v8a, armeabi-v7a and x86_64

Interface

CLI

Earliest failure stage

Native analysis or reconstruction

Relevant output or evidence

APK libflutter.so string dart_version on main
Flutter Gallery 2.9.2 (sha256 659b5fc6…, the verify-lane fixture) 2.14.0-151.0.dev (dev) (Tue May 25 10:58:39 2021 -0700) null (all 3 ABIs)
A Flutter 3.29 release app (Dart 3.7.2) 3.7.2 (stable) (Tue Mar 11 04:27:50 2025 -0700) on "android_arm64" null (all 3 ABIs)

Neither engine contains Dart VM version anywhere. Obtained with strings -a and rea's own scan.

Typed outcome or recovery expected

dart_version set to the embedded string; dart_version_capped only when two different versions are found.

Analysis or suspected cause

Source-derived: LabeledStringScanner (src/flutter/FlutterPayloadScan.ts) only accepts a printable run starting with Dart VM version:. That label comes from the standalone Dart VM's --version output. Release engines embed Dart's Version::String() (version_in.cc), NUL-delimited and unlabeled.

A fix is on my fork, branch fix/flutter-dart-version (baf98c755, on main e54bf1006). It adds a second grammar for the whole printable run, <version> (<channel>) (<commit time>) with an optional on "<os>_<arch>" suffix, keeps the labeled form, and updates the Gallery expectations. Three new tests fail on main and pass with it; src/flutter/ plus the Flutter boundary test (173), check:fast and verify:flutter against the real Gallery APK pass.

I opened an issue rather than a PR because the fix matches by shape, not by label, which goes against how the scanner trusts strings now. A trade-off for you to decide:

  • Another string in an engine with exactly this shape (1.2.3 (word) (text), whole run) would be reported too. None of the six engines has one.
  • Unlabeled runs that do not match are ignored and never set dart_version_capped.
  • Older SDKs (roughly Flutter 1.x) may print <version> (<commit time>) on "<os>_<arch>" with no channel. I had no such engine, so the branch keeps the channel required.

If the approach suits you, I can open the branch as a PR.

Additional context

The fix and tests were written by an AI agent; the tests were rerun independently before filing.

Originally created by @JayOfTheKeyboard on GitHub (Oct 26, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/7226 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Native analysis or decompilation ### Observed behavior `identify_flutter_build` returns `dart_version: null` for every real Flutter engine I checked, including the Flutter Gallery 2.9.2 APK that `verify:flutter` pins. The engines do carry their Dart version, without the `Dart VM version:` label the scanner waits for. ### Reproduction 1. `npm run verify:flutter -- --apk flutter_gallery_Android.apk --expectations scripts/fixtures/flutter-gallery-expectations.json` on main, or `rea identify-flutter-build` on any release APK. 2. Read `dart_version` for each ABI: `null`. 3. `strings -a lib/arm64-v8a/libflutter.so | grep -E '^[0-9]+\.[0-9]+\.[0-9]+.* \((stable|beta|dev)\)'` shows the version string. Reproduces every time, on six engines (three ABIs each from two APKs). ### Expected behavior `dart_version` reports the Dart version string the engine embeds, e.g. `3.7.2 (stable) (Tue Mar 11 04:27:50 2025 -0700) on "android_arm64"`. ### Impact and scope The field is null on all release engines I could check, so callers never get the Dart version from a real APK. `docs/flutter-analysis.md` says "Release engine builds often strip the `Dart VM version` string", but the version is present, just unlabeled. No effect on other fields. ### REA version main e54bf1006 (6.8.0) ### Runtime and platform Node.js 24.22.1, Fedora 44, x86_64 ### Target and artifact context Android APKs, `libflutter.so` for arm64-v8a, armeabi-v7a and x86_64 ### Interface CLI ### Earliest failure stage Native analysis or reconstruction ### Relevant output or evidence | APK | `libflutter.so` string | `dart_version` on main | |---|---|---| | Flutter Gallery 2.9.2 (sha256 `659b5fc6…`, the verify-lane fixture) | `2.14.0-151.0.dev (dev) (Tue May 25 10:58:39 2021 -0700)` | `null` (all 3 ABIs) | | A Flutter 3.29 release app (Dart 3.7.2) | `3.7.2 (stable) (Tue Mar 11 04:27:50 2025 -0700) on "android_arm64"` | `null` (all 3 ABIs) | Neither engine contains `Dart VM version` anywhere. Obtained with `strings -a` and rea's own scan. ### Typed outcome or recovery expected `dart_version` set to the embedded string; `dart_version_capped` only when two different versions are found. ### Analysis or suspected cause Source-derived: `LabeledStringScanner` (`src/flutter/FlutterPayloadScan.ts`) only accepts a printable run starting with `Dart VM version:`. That label comes from the standalone Dart VM's `--version` output. Release engines embed Dart's `Version::String()` ([version_in.cc](https://github.com/dart-lang/sdk/blob/main/runtime/vm/version_in.cc)), NUL-delimited and unlabeled. A fix is on my fork, branch [`fix/flutter-dart-version`](https://github.com/JayOfTheKeyboard/rea/compare/main...JayOfTheKeyboard:rea:fix/flutter-dart-version) (baf98c755, on main e54bf1006). It adds a second grammar for the whole printable run, `<version> (<channel>) (<commit time>)` with an optional ` on "<os>_<arch>"` suffix, keeps the labeled form, and updates the Gallery expectations. Three new tests fail on main and pass with it; `src/flutter/` plus the Flutter boundary test (173), `check:fast` and `verify:flutter` against the real Gallery APK pass. I opened an issue rather than a PR because the fix matches by shape, not by label, which goes against how the scanner trusts strings now. A trade-off for you to decide: - Another string in an engine with exactly this shape (`1.2.3 (word) (text)`, whole run) would be reported too. None of the six engines has one. - Unlabeled runs that do not match are ignored and never set `dart_version_capped`. - Older SDKs (roughly Flutter 1.x) may print `<version> (<commit time>) on "<os>_<arch>"` with no channel. I had no such engine, so the branch keeps the channel required. If the approach suits you, I can open the branch as a PR. ### Additional context The fix and tests were written by an AI agent; the tests were rerun independently before filing.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#4306
No description provided.