Skip to content

Commit

Permalink
Catch invalid sizes during yoga layout (TextureGroup#1376)
Browse files Browse the repository at this point in the history
  • Loading branch information
wiseoldduck authored and hebertialmeida committed May 10, 2019
1 parent 54ddc3d commit 4a16e99
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
18 changes: 14 additions & 4 deletions Source/ASDisplayNode+Yoga.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#import <AsyncDisplayKit/ASYogaUtilities.h>
#import <AsyncDisplayKit/ASCollections.h>
#import <AsyncDisplayKit/ASDisplayNode+Beta.h>
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
Expand Down Expand Up @@ -183,6 +184,13 @@ - (ASLayout *)layoutForYogaNode
CGSize size = CGSizeMake(YGNodeLayoutGetWidth(yogaNode), YGNodeLayoutGetHeight(yogaNode));
CGPoint position = CGPointMake(YGNodeLayoutGetLeft(yogaNode), YGNodeLayoutGetTop(yogaNode));

if (!ASIsCGSizeValidForSize(size)) {
size = CGSizeZero;
}

if (!ASIsCGPositionValidForLayout(position)) {
position = CGPointZero;
}
return [ASLayout layoutWithLayoutElement:self size:size position:position sublayouts:nil];
}

Expand All @@ -205,6 +213,9 @@ - (void)setupYogaCalculatedLayout

// The layout for self should have position CGPointNull, but include the calculated size.
CGSize size = CGSizeMake(YGNodeLayoutGetWidth(yogaNode), YGNodeLayoutGetHeight(yogaNode));
if (!ASIsCGSizeValidForSize(size)) {
size = CGSizeZero;
}
ASLayout *layout = [ASLayout layoutWithLayoutElement:self size:size sublayouts:sublayouts];

#if ASDISPLAYNODE_ASSERTIONS_ENABLED
Expand Down Expand Up @@ -398,11 +409,10 @@ - (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize
NSLog(@"******************** STARTING YOGA -> ASLAYOUT CREATION ********************");
NSLog(@"****************************************************************************");
ASDisplayNodePerformBlockOnEveryYogaChild(self, ^(ASDisplayNode * _Nonnull node) {
NSLog(@" "); // Newline
NSLog(@"node = %@", node);
NSLog(@"style = %@", node.style);
NSLog(@"layout = %@", node.yogaCalculatedLayout);
YGNodePrint(node.yogaNode, (YGPrintOptions)(YGPrintOptionsStyle | YGPrintOptionsLayout));
YGNodePrint(node.style.yogaNode, (YGPrintOptions)(YGPrintOptionsStyle | YGPrintOptionsLayout));
NSCAssert(ASIsCGSizeValidForSize(node.yogaCalculatedLayout.size), @"Yoga layout returned an invalid size");
NSLog(@" "); // Newline
});
}
#endif /* YOGA_LAYOUT_LOGGING */
Expand Down
6 changes: 4 additions & 2 deletions Source/Layout/ASDimension.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,21 @@ ASDISPLAYNODE_INLINE BOOL AS_WARN_UNUSED_RESULT ASIsCGSizeValidForLayout(CGSize
return (ASPointsValidForLayout(size.width) && ASPointsValidForLayout(size.height));
}

// Note we want YGUndefined (10E20) to be considered invalid, so we have picked a smaller number than CGFLOAT_MAX/2.0
ASDISPLAYNODE_INLINE BOOL AS_WARN_UNUSED_RESULT ASPointsValidForSize(CGFloat points)
{
return ((isnormal(points) || points == 0.0) && points >= 0.0 && points < (FLT_MAX / 2.0));
return ((isnormal(points) || points == 0.0) && points >= 0.0 && points < 10000000.0);
}

ASDISPLAYNODE_INLINE BOOL AS_WARN_UNUSED_RESULT ASIsCGSizeValidForSize(CGSize size)
{
return (ASPointsValidForSize(size.width) && ASPointsValidForSize(size.height));
}

// Note we want YGUndefined (10E20) to be considered invalid, so we have picked a smaller number than CGFLOAT_MAX/2.0
ASDISPLAYNODE_INLINE BOOL ASIsCGPositionPointsValidForLayout(CGFloat points)
{
return ((isnormal(points) || points == 0.0) && points < (CGFLOAT_MAX / 2.0));
return ((isnormal(points) || points == 0.0) && points < 10000000.0);
}

ASDISPLAYNODE_INLINE BOOL ASIsCGPositionValidForLayout(CGPoint point)
Expand Down

0 comments on commit 4a16e99

Please sign in to comment.