Skip to content

fix a RenderBox.size access exception#74402

Merged
fluttergithubbot merged 4 commits into
flutter:masterfrom
xu-baolin:0121size
Jan 26, 2021
Merged

fix a RenderBox.size access exception#74402
fluttergithubbot merged 4 commits into
flutter:masterfrom
xu-baolin:0121size

Conversation

@xu-baolin

@xu-baolin xu-baolin commented Jan 21, 2021

Copy link
Copy Markdown
Member

Why does the exception happen

The EditableTextState will access RenderBox.size during rebuilding.
So, if the LayoutBuilder.builder returns a TextFormField widget, it will trigger the exception as follow when _RenderLayoutBuilder.performLayout is running,

I think this type of access is legal and we can use the RenderObject._doingThisLayoutWithCallback to distinguish this scenario.

======== Exception caught by widgets library =======================================================
The following assertion was thrown building UnmanagedRestorationScope:
RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout().
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1947 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout ||
              (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'


Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

The relevant error-causing widget was: 
  TextFormField file:///D:/My%20Documents/Desktop/flutter_app_test/lib/main.dart:84:13
To inspect this widget in Flutter DevTools, visit: http://127.0.0.1:58353/#/inspector?uri=http%3A%2F%2F127.0.0.1%3A58350%2F4G1hfjZhevY%3D%2F&inspectorRef=inspector-0
When the exception was thrown, this was the stack: 
#2      RenderBox.size.<anonymous closure> (package:flutter/src/rendering/box.dart:1947:13)
#3      RenderBox.size (package:flutter/src/rendering/box.dart:1960:6)
#4      EditableTextState._updateSizeAndTransform (package:flutter/src/widgets/editable_text.dart:2410:40)
#5      EditableTextState._openInputConnection (package:flutter/src/widgets/editable_text.dart:2016:7)
#6      EditableTextState.didUpdateWidget (package:flutter/src/widgets/editable_text.dart:1611:9)
...
====================================================================================================

Steps to reproduce

See the unit test for details.

Fixes #73676

@flutter-dashboard flutter-dashboard Bot added the framework flutter/packages/flutter repository. See also f: labels. label Jan 21, 2021
@google-cla google-cla Bot added the cla: yes label Jan 21, 2021
@xu-baolin
xu-baolin requested a review from chunhtai January 21, 2021 13:45
debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout ||
(RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent),
(RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent) ||
RenderObject.debugActiveLayout!.debugDoingThisLayoutWithCallback,

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.

can you move this into the if case in line 1945? This is more like something we want to short-circuit than checking in assert

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

buildCount++;
if (buildCount > 1) {
final _RenderLayoutSpy spy = tester.renderObject(find.byType(_LayoutSpy));
childSize = spy.size;

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.

what happen if we try to access the size in the first build? we should make sure this situation will throw.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The RO is null when first build and we can not access size by it.

@chunhtai chunhtai 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, except for indent issue

);
}
if (RenderObject.debugActiveLayout != null &&
!RenderObject.debugActiveLayout!.debugDoingThisLayoutWithCallback) {

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.

indent seems to be off.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Shouldn't it be indented by two spaces?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Got it now!

if (RenderObject.debugActiveLayout != null &&
!RenderObject.debugActiveLayout!.debugDoingThisLayoutWithCallback) {
assert(
debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout ||

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.

same here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Framework assertion in flutter/src/rendering/box.dart when using LayoutBuilder

3 participants