Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flutter_markdown] Invalid image URI crashes the app (instead of just showing an error at the image area) #158428

Open
kaboc opened this issue Nov 10, 2024 · 1 comment · May be fixed by flutter/packages#8058
Labels
a: images Loading, displaying, rendering images c: crash Stack traces logged to the console found in release: 3.24 Found to occur in 3.24 found in release: 3.27 Found to occur in 3.27 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: flutter_markdown flutter/packages flutter_markdown P2 Important issues not at the top of the work list package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team

Comments

@kaboc
Copy link
Contributor

kaboc commented Nov 10, 2024

Steps to reproduce

  1. Run the code sample below.
  2. Remove https from the URI in the text field.
  3. Press on the Preview button to go to the preview page.
  4. See the error is shown in the body of the page, i.e. in the Markdown widget.
  5. Go back to the main page with the back button.
  6. See the error is shown in the whole page, so the app is no longer working.

Expected results

The image is not rendered, and an error widget is used instead like below.

Actual results

The Markdown widget itself causes an error, and then, to make matters worse, the whole app stops working.

This means that when my app has a Markdown editing feature, just a user's mistype in an image URI in the Markdown image notation will get the user into trouble. Nothing can be done any more and the editor content is lost (unless the app has state restoration logic). As long as it can happen, I cannot use the package for production.

FYI, the error differs depending on the typo:

  • URI starting with ://

    Invalid empty scheme (at character 1)

  • URI starting with ttps://

    Unsupported operation: Cannot extract a file path from a ttps URI

Code sample

Code sample
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';

void main() {
  runApp(
    MaterialApp(home: const EditorPage()),
  );
}

class EditorPage extends StatefulWidget {
  const EditorPage();

  @override
  State<EditorPage> createState() => _EditorPageState();
}

class _EditorPageState extends State<EditorPage> {
  late final TextEditingController _controller = TextEditingController()
    ..text = '# Image\n\n'
        '![](https://avatars.githubusercontent.com/u/20254485?v=4)';

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            TextFormField(
              controller: _controller,
              maxLines: 10,
            ),
            ElevatedButton(
              onPressed: () => Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (_) => PreviewPage(markdown: _controller.text),
                ),
              ),
              child: const Text('Preview'),
            ),
          ],
        ),
      ),
    );
  }
}

class PreviewPage extends StatelessWidget {
  const PreviewPage({required this.markdown});

  final String markdown;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Preview'),
      ),
      body: SafeArea(
        child: Markdown(data: markdown),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

Logs

Logs
======== Exception caught by widgets library =======================================================
The following FormatException was thrown building MediaQuery(MediaQueryData(size: Size(694.0, 596.0), devicePixelRatio: 1.0, textScaler: no scaling, platformBrightness: Brightness.light, padding: EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, systemGestureInsets: EdgeInsets.zero, alwaysUse24HourFormat: true, accessibleNavigation: false, highContrast: false, onOffSwitchLabels: false, disableAnimations: false, invertColors: false, boldText: false, navigationMode: traditional, gestureSettings: DeviceGestureSettings(touchSlop: null), displayFeatures: [], supportsShowingSystemContextMenu: false)):
Invalid empty scheme (at character 1)
://avatars.githubusercontent.com/u/20254485?v=4
^

The relevant error-causing widget was: 
  SafeArea SafeArea:file:///D:/xxxx/lib/main.dart:64:13
When the exception was thrown, this was the stack: 
#0      _Uri._fail (dart:core/uri.dart:1737:5)
#1      new _Uri.notSimple (dart:core/uri.dart:1601:9)
#2      Uri.parse (dart:core/uri.dart:1138:17)
#3      MarkdownBuilder._buildImage (package:flutter_markdown/src/builder.dart:604:25)
#4      MarkdownBuilder.visitElementAfter (package:flutter_markdown/src/builder.dart:511:11)
#5      Element.accept (package:markdown/src/ast.dart:53:15)
#6      Element.accept (package:markdown/src/ast.dart:50:17)
#7      MarkdownBuilder.build (package:flutter_markdown/src/builder.dart:202:12)
#8      _MarkdownWidgetState._parseMarkdown (package:flutter_markdown/src/widget.dart:405:25)
#9      _MarkdownWidgetState.didChangeDependencies (package:flutter_markdown/src/widget.dart:348:5)
#10     StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5766:11)
#11     ComponentElement.mount (package:flutter/src/widgets/framework.dart:5593:5)
...     Normal element mounting (40 frames)
#51     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4468:16)
#52     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:7035:36)
#53     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:7047:32)
...     Normal element mounting (338 frames)
#391    Element.inflateWidget (package:flutter/src/widgets/framework.dart:4468:16)
#392    MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:7035:36)
#393    Element.updateChild (package:flutter/src/widgets/framework.dart:3963:18)
#394    Element.updateChildren (package:flutter/src/widgets/framework.dart:4150:32)
#395    MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:7060:17)
#396    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#397    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#398    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5780:11)
#399    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#400    StatefulElement.update (package:flutter/src/widgets/framework.dart:5803:5)
#401    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#402    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#403    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#404    ProxyElement.update (package:flutter/src/widgets/framework.dart:5946:5)
#405    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#406    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#407    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#408    ProxyElement.update (package:flutter/src/widgets/framework.dart:5946:5)
#409    _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:105:11)
#410    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#411    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#412    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5780:11)
#413    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#414    StatefulElement.update (package:flutter/src/widgets/framework.dart:5803:5)
#415    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#416    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#417    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#418    ProxyElement.update (package:flutter/src/widgets/framework.dart:5946:5)
#419    _InheritedNotifierElement.update (package:flutter/src/widgets/inherited_notifier.dart:105:11)
#420    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#421    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#422    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5780:11)
#423    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#424    StatefulElement.update (package:flutter/src/widgets/framework.dart:5803:5)
#425    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#426    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#427    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5780:11)
#428    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#429    StatefulElement.update (package:flutter/src/widgets/framework.dart:5803:5)
#430    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#431    SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6907:14)
#432    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#433    SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:6907:14)
#434    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#435    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#436    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#437    ProxyElement.update (package:flutter/src/widgets/framework.dart:5946:5)
#438    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#439    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#440    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#441    ProxyElement.update (package:flutter/src/widgets/framework.dart:5946:5)
#442    Element.updateChild (package:flutter/src/widgets/framework.dart:3941:15)
#443    ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5642:16)
#444    StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5780:11)
#445    Element.rebuild (package:flutter/src/widgets/framework.dart:5333:7)
#446    BuildScope._tryRebuild (package:flutter/src/widgets/framework.dart:2693:15)
#447    BuildScope._flushDirtyElements (package:flutter/src/widgets/framework.dart:2752:11)
#448    BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:3048:18)
#449    WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:1162:21)
#450    RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:468:5)
#451    SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1397:15)
#452    SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1318:9)
#453    SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1176:5)
#454    _invoke (dart:ui/hooks.dart:312:13)
#455    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:419:5)
#456    _drawFrame (dart:ui/hooks.dart:283:31)
====================================================================================================

Flutter Doctor output

Doctor output
[√] Flutter (Channel stable, 3.24.4, on Microsoft Windows [Version 10.0.22631.4317], locale ja-JP)
    • Flutter version 3.24.4 on channel stable at D:\xxxx\flutter\sdk
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 603104015d (2 weeks ago), 2024-10-24 08:01:25 -0700
    • Engine revision db49896cf2
    • Dart version 3.5.4
    • DevTools version 2.37.3

[√] Windows Version (Installed version of Windows is version 10 or higher)

[√] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
    • Android SDK at D:\xxxx\android\sdk
    • Platform android-35, build-tools 35.0.0
    • ANDROID_HOME = D:\xxxx\android\sdk
    • Java binary at: D:\xxxx\java\jdks\jbr-17.0.11\bin\java
    • Java version OpenJDK Runtime Environment JBR-17.0.11+1-1312.2-nomod (build 17.0.11+1-b1312.2)
    • All Android licenses accepted.

[X] Chrome - develop for the web (Cannot find Chrome executable at .\Google\Chrome\Application\chrome.exe)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.11.5)
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.11.35327.3
    • Windows 10 SDK version 10.0.22621.0

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/to/windows-android-setup for detailed instructions).

[√] IntelliJ IDEA Ultimate Edition (version 2024.2)
    • IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA 2023.2.5
    • Flutter plugin version 82.1.3
    • Dart plugin version 242.22855.32

[√] VS Code (version 1.94.2)
    • VS Code at C:\Users\xxxx\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.98.0

[√] Connected device (2 available)
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.22631.4317]
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 130.0.2849.56

[√] Network resources
    • All expected network resources are available.

! Doctor found issues in 2 categories.
@danagbemava-nc danagbemava-nc added the in triage Presently being triaged by the triage team label Nov 11, 2024
@danagbemava-nc
Copy link
Member

Reproducible using the code sample and steps provided above.

flutter doctor -v
[✓] Flutter (Channel stable, 3.24.4, on macOS 15.0.1 24A348 darwin-arm64, locale en-US)
    • Flutter version 3.24.4 on channel stable at /Users/deanli/dev/stable
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 603104015d (3 weeks ago), 2024-10-24 08:01:25 -0700
    • Engine revision db49896cf2
    • Dart version 3.5.4
    • DevTools version 2.37.3
[!] Flutter (Channel master, 3.27.0-1.0.pre.443, on macOS 15.0.1 24A348 darwin-arm64, locale en-US)
    • Flutter version 3.27.0-1.0.pre.443 on channel master at /Users/deanli/dev/master
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 5fd650f68b (6 hours ago), 2024-11-10 23:02:25 -0500
    • Engine revision 01c76e42c2
    • Dart version 3.7.0 (build 3.7.0-123.0.dev)
    • DevTools version 2.41.0-dev.2

@danagbemava-nc danagbemava-nc added a: images Loading, displaying, rendering images package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team has reproducible steps The issue has been confirmed reproducible and is ready to work on p: flutter_markdown flutter/packages flutter_markdown found in release: 3.24 Found to occur in 3.24 found in release: 3.27 Found to occur in 3.27 c: crash Stack traces logged to the console and removed in triage Presently being triaged by the triage team labels Nov 11, 2024
@stuartmorgan stuartmorgan added P2 Important issues not at the top of the work list triaged-ecosystem Triaged by Ecosystem team labels Nov 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: images Loading, displaying, rendering images c: crash Stack traces logged to the console found in release: 3.24 Found to occur in 3.24 found in release: 3.27 Found to occur in 3.27 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: flutter_markdown flutter/packages flutter_markdown P2 Important issues not at the top of the work list package flutter/packages repository. See also p: labels. team-ecosystem Owned by Ecosystem team triaged-ecosystem Triaged by Ecosystem team
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants