From 8ae4854c64024c1c2cd6c7c458fb62901e83b59e Mon Sep 17 00:00:00 2001 From: Dan Chevalier Date: Fri, 25 Aug 2023 15:38:29 -0400 Subject: [PATCH 1/7] Limit text view to 2^16 characters to prevent it from crashing --- .../network_request_inspector_views.dart | 12 +++------- .../lib/src/shared/common_widgets.dart | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart index 40444b59e0c..f1bf477308a 100644 --- a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart +++ b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart @@ -156,13 +156,10 @@ class HttpRequestView extends StatelessWidget { ? requestContentType.any((element) => element.contains('json')) : requestContentType.contains('json'); - Widget child; + Widget child; child = isJson ? JsonViewer(encodedJson: data.requestBody!) - : Text( - data.requestBody!, - style: theme.fixedFontStyle, - ); + : TextViewer(text: data.requestBody!); return Padding( padding: const EdgeInsets.all(denseSpacing), child: SingleChildScrollView( @@ -356,10 +353,7 @@ class HttpTextResponseViewer extends StatelessWidget { return switch (currentLocalResponseType) { NetworkResponseViewType.json => JsonViewer(encodedJson: responseBody), - NetworkResponseViewType.text => Text( - responseBody, - style: textStyle, - ), + NetworkResponseViewType.text => TextViewer(text: responseBody), _ => const SizedBox(), }; }, diff --git a/packages/devtools_app/lib/src/shared/common_widgets.dart b/packages/devtools_app/lib/src/shared/common_widgets.dart index 5ee808bb6b5..3a4ea3101fe 100644 --- a/packages/devtools_app/lib/src/shared/common_widgets.dart +++ b/packages/devtools_app/lib/src/shared/common_widgets.dart @@ -1264,6 +1264,30 @@ class JsonViewer extends StatefulWidget { State createState() => _JsonViewerState(); } +class TextViewer extends StatelessWidget { + const TextViewer({ + super.key, + required this.text, + }); + final String text; + static const _maxLength = 65536; //2^16 + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final String displayText; + // Limit the length of the displayed text to _MAX_LENGTH + if (text.length > _maxLength) { + displayText = '${text.substring(0, min(_maxLength, text.length))}...'; + } else { + displayText = text; + } + return Text( + displayText, + style: theme.fixedFontStyle, + ); + } +} + class _JsonViewerState extends State with ProvidedControllerMixin { late Future _initializeTree; From 8891171cb694b7b340a88eaa2fa8da1c6c469917 Mon Sep 17 00:00:00 2001 From: Dan Chevalier Date: Fri, 25 Aug 2023 15:47:36 -0400 Subject: [PATCH 2/7] lint --- .../src/screens/network/network_request_inspector_views.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart index f1bf477308a..91abb5e2956 100644 --- a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart +++ b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart @@ -156,7 +156,7 @@ class HttpRequestView extends StatelessWidget { ? requestContentType.any((element) => element.contains('json')) : requestContentType.contains('json'); - Widget child; + Widget child; child = isJson ? JsonViewer(encodedJson: data.requestBody!) : TextViewer(text: data.requestBody!); From 8f4b3f3c2c637e071c7d6c8fae4bcc73af2928be Mon Sep 17 00:00:00 2001 From: Dan Chevalier Date: Fri, 25 Aug 2023 15:53:25 -0400 Subject: [PATCH 3/7] next release note update --- packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md index accd625103e..d04b750e035 100644 --- a/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md +++ b/packages/devtools_app/release_notes/NEXT_RELEASE_NOTES.md @@ -24,7 +24,7 @@ TODO: Remove this section if there are not any general updates. TODO: Remove this section if there are not any general updates. ## Network profiler updates -TODO: Remove this section if there are not any general updates. +- Fixed a crash with large text in request or response - [#6254](https://github.com/flutter/devtools/pull/6254) ## Logging updates TODO: Remove this section if there are not any general updates. From cf4617fabd523c2367c6601585c1314d496fe6cf Mon Sep 17 00:00:00 2001 From: Dan Chevalier Date: Mon, 28 Aug 2023 09:31:54 -0400 Subject: [PATCH 4/7] unused theme --- .../lib/src/screens/network/network_request_inspector_views.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart index 91abb5e2956..dcfeb013fb5 100644 --- a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart +++ b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart @@ -142,7 +142,6 @@ class HttpRequestView extends StatelessWidget { return ValueListenableBuilder( valueListenable: data.requestUpdatedNotifier, builder: (context, __, ___) { - final theme = Theme.of(context); final requestHeaders = data.requestHeaders; final requestContentType = requestHeaders?['content-type'] ?? ''; final isLoading = data.isFetchingFullData; From 442f7de1135e33847d383d3e78636cbadfc9d138 Mon Sep 17 00:00:00 2001 From: Dan Chevalier Date: Mon, 28 Aug 2023 11:25:27 -0400 Subject: [PATCH 5/7] Ben Comments --- .../network/network_request_inspector_views.dart | 15 +++++++++++++-- .../lib/src/shared/common_widgets.dart | 16 +++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart index dcfeb013fb5..92812a2e44c 100644 --- a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart +++ b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart @@ -142,6 +142,7 @@ class HttpRequestView extends StatelessWidget { return ValueListenableBuilder( valueListenable: data.requestUpdatedNotifier, builder: (context, __, ___) { + final theme = Theme.of(context); final requestHeaders = data.requestHeaders; final requestContentType = requestHeaders?['content-type'] ?? ''; final isLoading = data.isFetchingFullData; @@ -158,7 +159,12 @@ class HttpRequestView extends StatelessWidget { Widget child; child = isJson ? JsonViewer(encodedJson: data.requestBody!) - : TextViewer(text: data.requestBody!); + // Using TextViewer fixes + // https://github.com/flutter/devtools/issues/5973 + : TextViewer( + text: data.requestBody!, + style: theme.fixedFontStyle, + ); return Padding( padding: const EdgeInsets.all(denseSpacing), child: SingleChildScrollView( @@ -352,7 +358,12 @@ class HttpTextResponseViewer extends StatelessWidget { return switch (currentLocalResponseType) { NetworkResponseViewType.json => JsonViewer(encodedJson: responseBody), - NetworkResponseViewType.text => TextViewer(text: responseBody), + // Using TextViewer fixes + // https://github.com/flutter/devtools/issues/5973 + NetworkResponseViewType.text => TextViewer( + text: responseBody, + style: textStyle, + ), _ => const SizedBox(), }; }, diff --git a/packages/devtools_app/lib/src/shared/common_widgets.dart b/packages/devtools_app/lib/src/shared/common_widgets.dart index 3a4ea3101fe..921a625bdc9 100644 --- a/packages/devtools_app/lib/src/shared/common_widgets.dart +++ b/packages/devtools_app/lib/src/shared/common_widgets.dart @@ -1264,26 +1264,32 @@ class JsonViewer extends StatefulWidget { State createState() => _JsonViewerState(); } +/// A wrapper for a Text widget, which allows for concatenating text if it +/// becomes too long. class TextViewer extends StatelessWidget { const TextViewer({ super.key, required this.text, + this.maxLength = 65536, //2^16 + this.style, }); + final String text; - static const _maxLength = 65536; //2^16 + final int maxLength; + final TextStyle? style; + @override Widget build(BuildContext context) { - final theme = Theme.of(context); final String displayText; // Limit the length of the displayed text to _MAX_LENGTH - if (text.length > _maxLength) { - displayText = '${text.substring(0, min(_maxLength, text.length))}...'; + if (text.length > maxLength) { + displayText = '${text.substring(0, min(maxLength, text.length))}...'; } else { displayText = text; } return Text( displayText, - style: theme.fixedFontStyle, + style: style, ); } } From fcbeee2cd70f89475468c9e88fcc4442646ccb22 Mon Sep 17 00:00:00 2001 From: Dan Chevalier Date: Mon, 28 Aug 2023 15:37:32 -0400 Subject: [PATCH 6/7] better comment --- .../src/screens/network/network_request_inspector_views.dart | 4 ---- packages/devtools_app/lib/src/shared/common_widgets.dart | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart index 92812a2e44c..d137d522fb0 100644 --- a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart +++ b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart @@ -159,8 +159,6 @@ class HttpRequestView extends StatelessWidget { Widget child; child = isJson ? JsonViewer(encodedJson: data.requestBody!) - // Using TextViewer fixes - // https://github.com/flutter/devtools/issues/5973 : TextViewer( text: data.requestBody!, style: theme.fixedFontStyle, @@ -358,8 +356,6 @@ class HttpTextResponseViewer extends StatelessWidget { return switch (currentLocalResponseType) { NetworkResponseViewType.json => JsonViewer(encodedJson: responseBody), - // Using TextViewer fixes - // https://github.com/flutter/devtools/issues/5973 NetworkResponseViewType.text => TextViewer( text: responseBody, style: textStyle, diff --git a/packages/devtools_app/lib/src/shared/common_widgets.dart b/packages/devtools_app/lib/src/shared/common_widgets.dart index 921a625bdc9..60da4b70820 100644 --- a/packages/devtools_app/lib/src/shared/common_widgets.dart +++ b/packages/devtools_app/lib/src/shared/common_widgets.dart @@ -1275,6 +1275,8 @@ class TextViewer extends StatelessWidget { }); final String text; + // TODO: change the maxLength if we determine a more appropriate limit + // in https://github.com/flutter/devtools/issues/6263. final int maxLength; final TextStyle? style; From f8a81dd8eb5e4c00f9e03b575b92de64f728d874 Mon Sep 17 00:00:00 2001 From: Dan Chevalier Date: Mon, 28 Aug 2023 15:38:07 -0400 Subject: [PATCH 7/7] rrr --- packages/devtools_app/lib/src/shared/common_widgets.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/devtools_app/lib/src/shared/common_widgets.dart b/packages/devtools_app/lib/src/shared/common_widgets.dart index 60da4b70820..60035f5d551 100644 --- a/packages/devtools_app/lib/src/shared/common_widgets.dart +++ b/packages/devtools_app/lib/src/shared/common_widgets.dart @@ -1283,7 +1283,7 @@ class TextViewer extends StatelessWidget { @override Widget build(BuildContext context) { final String displayText; - // Limit the length of the displayed text to _MAX_LENGTH + // Limit the length of the displayed text to maxLength if (text.length > maxLength) { displayText = '${text.substring(0, min(maxLength, text.length))}...'; } else {