Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-8381] iOS: ENSURE_ARG_OR_NIL_AT_INDEX macro does not handle NSNull instance

GitHub Issuen/a
TypeNew Feature
PriorityLow
StatusOpen
ResolutionUnresolved
Affected Version/sRelease 1.8.2
Fix Version/sn/a
ComponentsiOS
Labelsn/a
ReporterPaul Mietz Egli
AssigneeUnknown
Created2012-03-13T10:54:34.000+0000
Updated2018-03-06T18:57:50.000+0000

Description

In my native module, I check for optional arguments to a method using the ENSURE_ARG_OR_NIL_AT_INDEX macro as follows:
- (id)myMethod:(id)args {
    NSString * requiredArg;
    NSString * optionalArg1;
    NSNumber * optionalArg2;
    
    ENSURE_ARG_AT_INDEX(requiredArg, args, 0, NSString);
    ENSURE_ARG_OR_NIL_AT_INDEX(optionalArg1, args, 1, NSString);
    ENSURE_ARG_OR_NIL_AT_INDEX(optionalArg2, args, 2, NSNumber);
    
    /* remainder of method */
}
This code is throwing an error when optionalArg1 is null:
[ERROR] Invalid type passed to function. expected: NSString, was: NSNull  in -[TDDatabaseProxy(Insertion) putRevision:] (TDDatabaseProxy+TDDatabaseProxy_Insertion.m:43)
Fix is to add a check for NSNull in the macro as shown on line 13 below:
#define ENSURE_ARG_OR_NIL_AT_INDEX(out,args,index,type) \
if (args==nil || args==[NSNull null]) \
{ \
out = nil; \
} \
else if ([args isKindOfClass:[NSArray class]]) { \
if ([args count]>index) {\
out = [args objectAtIndex:index]; \
}\
else { \
out = nil; \
} \
if (out && ![out isKindOfClass:[NSNull class]] && ![out isKindOfClass:[type class]]) { \
[self throwException:TiExceptionInvalidType subreason:[NSString stringWithFormat:@"expected: %@, was: %@",[type class],[out class]] location:CODELOCATION]; \
} \
} \

Comments

  1. Paul Mietz Egli 2012-04-16

    Here's a version of the macro that converts NSNull to nil instead, which more closely matches the intent of passing a JavaScript null to a module function. This is what I'm currently using for my projects.
       #define ENSURE_ARG_OR_NIL_AT_INDEX(out,args,index,type) \
       if (args==nil || args==[NSNull null]) \
       { \
       out = nil; \
       } \
       else if ([args isKindOfClass:[NSArray class]]) { \
       if ([args count]>index) {\
       out = [args objectAtIndex:index]; \
       }\
       else { \
       out = nil; \
       } \
       if ([out isKindOfClass:[NSNull class]]) { \
       out = nil;\
       }\
       if (out && ![out isKindOfClass:[type class]]) { \
       [self throwException:TiExceptionInvalidType subreason:[NSString stringWithFormat:@"expected: %@, was: %@",[type class],[out class]] location:CODELOCATION]; \
       } \
       } \
       

JSON Source