From 5a3089aaeecf124302c4b82bfde9348fcaf0fd43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Thu, 25 Oct 2018 04:32:45 -0700 Subject: [ios, macos] Fixed crash on nullary vararg expression function Equate the nullary and unary forms of vararg-style aftermarket expression functions when converting to JSON objects. --- platform/darwin/src/NSExpression+MGLAdditions.mm | 9 ++++-- platform/darwin/test/MGLExpressionTests.mm | 38 +++++++++++++++++++++++- platform/ios/CHANGELOG.md | 1 + platform/macos/CHANGELOG.md | 1 + 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm index 1a8dff060c..cb7f30f65a 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -1065,9 +1065,11 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { [expressionObject addObject:self.operand.mgl_jsonExpressionObject]; return expressionObject; } else if ([function isEqualToString:@"MGL_IF"] || + [function isEqualToString:@"MGL_IF:"] || [function isEqualToString:@"mgl_if:"]) { return self.mgl_jsonIfExpressionObject; } else if ([function isEqualToString:@"MGL_MATCH"] || + [function isEqualToString:@"MGL_MATCH:"] || [function isEqualToString:@"mgl_match:"]) { return self.mgl_jsonMatchExpressionObject; } else if ([function isEqualToString:@"mgl_coalesce:"] || @@ -1104,7 +1106,8 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { } [NSException raise:NSInvalidArgumentException format:@"Casting expression to %@ not yet implemented.", type]; - } else if ([function isEqualToString:@"MGL_FUNCTION"]) { + } else if ([function isEqualToString:@"MGL_FUNCTION"] || + [function isEqualToString:@"MGL_FUNCTION:"]) { NSExpression *op = self.arguments.firstObject; if (op.expressionType == NSConstantValueExpressionType && [op.constantValue isEqualToString:@"collator"]) { @@ -1257,7 +1260,7 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { } - (id)mgl_jsonMatchExpressionObject { - BOOL isAftermarketFunction = [self.function isEqualToString:@"MGL_MATCH"]; + BOOL isAftermarketFunction = [self.function hasPrefix:@"MGL_MATCH"]; NSUInteger minimumIndex = isAftermarketFunction ? 1 : 0; NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"match", (isAftermarketFunction ? self.arguments.firstObject : self.operand).mgl_jsonExpressionObject, nil]; @@ -1283,7 +1286,7 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) { } - (id)mgl_jsonIfExpressionObject { - BOOL isAftermarketFunction = [self.function isEqualToString:@"MGL_IF"]; + BOOL isAftermarketFunction = [self.function hasPrefix:@"MGL_IF"]; NSUInteger minimumIndex = isAftermarketFunction ? 1 : 0; NSExpression *firstCondition; id condition; diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm index 6cb7bfdc3d..1b0630cef3 100644 --- a/platform/darwin/test/MGLExpressionTests.mm +++ b/platform/darwin/test/MGLExpressionTests.mm @@ -988,9 +988,45 @@ using namespace std::string_literals; NSArray *jsonExpression = @[@"random", @1, @2, @3, @4, @5]; XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression); XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression); - expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('random', 1, 2, 3, 4)"]; + } + { + NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('random', 1, 2, 3, 4)"]; XCTAssertThrowsSpecificNamed([expression expressionValueWithObject:nil context:nil], NSException, NSInvalidArgumentException); } + { + NSArray *arguments = @[ + MGLConstantExpression(@"one"), MGLConstantExpression(@1), + [NSExpression expressionForVariable:@"one"], + ]; + NSExpression *nullaryExpression = [NSExpression expressionForFunction:@"MGL_LET" arguments:arguments]; + NSExpression *unaryExpression = [NSExpression expressionForFunction:@"MGL_LET:" arguments:arguments]; + XCTAssertEqualObjects(nullaryExpression.mgl_jsonExpressionObject, unaryExpression.mgl_jsonExpressionObject); + } + { + NSArray *arguments = @[ + [NSExpression expressionForVariable:@"x"], + MGLConstantExpression(@YES), MGLConstantExpression(@"yes"), + MGLConstantExpression(@NO), MGLConstantExpression(@"no"), + ]; + NSExpression *nullaryExpression = [NSExpression expressionForFunction:@"MGL_MATCH" arguments:arguments]; + NSExpression *unaryExpression = [NSExpression expressionForFunction:@"MGL_MATCH:" arguments:arguments]; + XCTAssertEqualObjects(nullaryExpression.mgl_jsonExpressionObject, unaryExpression.mgl_jsonExpressionObject); + } + { + NSArray *arguments = @[ + [NSPredicate predicateWithValue:YES], + MGLConstantExpression(@"yes"), MGLConstantExpression(@"no"), + ]; + NSExpression *nullaryExpression = [NSExpression expressionForFunction:@"MGL_IF" arguments:arguments]; + NSExpression *unaryExpression = [NSExpression expressionForFunction:@"MGL_IF:" arguments:arguments]; + XCTAssertEqualObjects(nullaryExpression.mgl_jsonExpressionObject, unaryExpression.mgl_jsonExpressionObject); + } + { + NSArray *arguments = @[MGLConstantExpression(@"zoom")]; + NSExpression *nullaryExpression = [NSExpression expressionForFunction:@"MGL_FUNCTION" arguments:arguments]; + NSExpression *unaryExpression = [NSExpression expressionForFunction:@"MGL_FUNCTION:" arguments:arguments]; + XCTAssertEqualObjects(nullaryExpression.mgl_jsonExpressionObject, unaryExpression.mgl_jsonExpressionObject); + } } #pragma mark - Localization tests diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 00a085125e..b37087d189 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -7,6 +7,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT ### Styles and rendering * Added the ability to style symbol layers labels with multiple fonts and text sizes via the `format` expression operator. ([#12624](https://github.com/mapbox/mapbox-gl-native/pull/12624)) +* Fixed a crash when using the `MGL_LET`, `MGL_MATCH`, `MGL_IF`, or `MGL_FUNCTION` functions without a colon inside an `NSExpression` or `NSPredicate` format string. ([#13189](https://github.com/mapbox/mapbox-gl-native/pull/13189)) ### Offline maps diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md index 1e04215fcb..d9c70cb24a 100644 --- a/platform/macos/CHANGELOG.md +++ b/platform/macos/CHANGELOG.md @@ -6,6 +6,7 @@ * Added an `MGLSymbolStyleLayer.symbolZOrder` property for forcing point features in a symbol layer to be layered in the same order that they are specified in the layer’s associated source. ([#12783](https://github.com/mapbox/mapbox-gl-native/pull/12783)) * Fixed a crash when a style layer `*-pattern` property evaluates to nil for a particular feature. ([#12896](https://github.com/mapbox/mapbox-gl-native/pull/12896)) +* Fixed a crash when using the `MGL_LET`, `MGL_MATCH`, `MGL_IF`, or `MGL_FUNCTION` functions without a colon inside an `NSExpression` or `NSPredicate` format string. ([#13189](https://github.com/mapbox/mapbox-gl-native/pull/13189)) * Fixed an issue where fill and line layers would occasionally flicker on zoom ([#12982](https://github.com/mapbox/mapbox-gl-native/pull/12982)) ### Offline maps -- cgit v1.2.1