dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.07k stars 1.56k forks source link

DateTime.tryParse non consistent behavior across platforms #56444

Open vasilich6107 opened 4 weeks ago

vasilich6107 commented 4 weeks ago

Steps to reproduce

Run reproduction code on iOS, Android, Web

Expected results

Consistent result.

Actual results

ios/anroid parses phone number into date time

Code sample

Code sample ```dart Text( (DateTime.tryParse('+6477191451')?.toIso8601String()).toString(), ), ```

Screenshots or Video

Screenshots / Video demonstration image

Logs

Logs ```console [Paste your logs here] ```

Flutter Doctor output

Doctor output ```console Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel master, 3.24.0-1.0.pre.533, on macOS 14.5 23F79 darwin-arm64, locale en-US) [!] Android toolchain - develop for Android devices (Android SDK version 33.0.1) ✗ cmdline-tools component is missing Run `path/to/sdkmanager --install "cmdline-tools;latest"` See https://developer.android.com/studio/command-line for more details. ✗ Android license status unknown. Run `flutter doctor --android-licenses` to accept the SDK licenses. See https://flutter.dev/to/macos-android-setup for more details. [✓] Xcode - develop for iOS and macOS (Xcode 15.4) [✓] Chrome - develop for the web [!] Android Studio (version unknown) ✗ Unable to determine Android Studio version. [✓] Android Studio (version 2023.3) [✓] IntelliJ IDEA Ultimate Edition (version 2024.1.1) [✓] IntelliJ IDEA Community Edition (version 2023.1.5) [✓] IntelliJ IDEA Community Edition (version 2024.1.3) [✓] IntelliJ IDEA Community Edition (version 2023.1.5) [✓] VS Code (version 1.90.1) [✓] Connected device (7 available) ! Error: Browsing on the local area network for iPad (2). Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac. The device must be opted into Developer Mode to connect wirelessly. (code -27) [✓] Network resources ```
dart-github-bot commented 4 weeks ago

Summary: The DateTime.tryParse method exhibits inconsistent behavior across platforms when parsing phone numbers. On iOS and Android, it incorrectly interprets phone numbers as dates, while on the web, it returns null as expected.

lrhn commented 4 weeks ago

The string +6477191451 should be parsed as +647719-14-51 (a six-digit year with an optional sign, two-digit month and two-digit day).

The month and day are obviously bogus, but we still allow overflow in parsing (there is an issue about that somewhere, it should probaby be an error to have invalid month or date when parsing).

That means the actual date represented is +647720-03-22 or there-about. A quick calculation puts this at 235,800,612,866 days after epoch, far beyond the allowed ±100,000,000 days that DateTime supports. So this should be an error.

Most likely issue is that the VM internal computation overflows, and is not checking for that eagerly. (Which is hard because a constructor call can technically do DateTime(275760, 12, -1000), which would be just outside the allowed range if not for the date value, which then pulls it back into valid range. You can't tell if the value is too big before adding up all the parts, but if the value overflows during that, you lose the information. The DateTime.parse obviously can't have a -1000 day, but it goes through the same contstructor with the numbers it does have.

A 64-bit signed number overflows around year 292277 after epoch if counting microseconds.