Skip to content

Commit

Permalink
Merge branch 'fix-is-primitive-invalid-index-gh337'
Browse files Browse the repository at this point in the history
  • Loading branch information
svaarala committed Sep 11, 2015
2 parents 827a63a + 2fbb154 commit ebef1ee
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 31 deletions.
3 changes: 3 additions & 0 deletions RELEASES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,9 @@ Planned
* Fix JX parsing bug which caused strings like "1Infinity" to be parsed as
negative infinity instead of causing a SyntaxError (GH-247)

* Fix duk_is_primitive() return value for invalid index, was incorrectly 1
(GH-337)

* Fix compile error from array fast path when using low memory options
(GH-174)

Expand Down
11 changes: 10 additions & 1 deletion src/duk_api_public.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,16 @@ DUK_EXTERNAL_DECL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t i
DUK_EXTERNAL_DECL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t index);
DUK_EXTERNAL_DECL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t index);

DUK_EXTERNAL_DECL duk_bool_t duk_is_primitive(duk_context *ctx, duk_idx_t index);
#define duk_is_primitive(ctx,index) \
duk_check_type_mask((ctx), (index), DUK_TYPE_MASK_UNDEFINED | \
DUK_TYPE_MASK_NULL | \
DUK_TYPE_MASK_BOOLEAN | \
DUK_TYPE_MASK_NUMBER | \
DUK_TYPE_MASK_STRING | \
DUK_TYPE_MASK_BUFFER | \
DUK_TYPE_MASK_POINTER | \
DUK_TYPE_MASK_LIGHTFUNC)

#define duk_is_object_coercible(ctx,index) \
duk_check_type_mask((ctx), (index), DUK_TYPE_MASK_BOOLEAN | \
DUK_TYPE_MASK_NUMBER | \
Expand Down
7 changes: 0 additions & 7 deletions src/duk_api_stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -2842,13 +2842,6 @@ DUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t index
return 0;
}

/* XXX: make macro in API */
DUK_EXTERNAL duk_bool_t duk_is_primitive(duk_context *ctx, duk_idx_t index) {
DUK_ASSERT_CTX_VALID(ctx);

return !duk_is_object(ctx, index);
}

DUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t index) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_hobject *h;
Expand Down
52 changes: 52 additions & 0 deletions tests/api/test-bug-is-primitive-invalid-index-gh337.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Bug in duk_is_primitive() prior to Duktape 1.3.0: returns 1 for invalid
* index.
*
* https://github.com/svaarala/duktape/issues/337
*/

/*===
*** test_1 (duk_safe_call)
0
final top: 0
==> rc=0, result='undefined'
*** test_2 (duk_safe_call)
0
final top: 0
==> rc=0, result='undefined'
*** test_3 (duk_safe_call)
1
0
final top: 1
==> rc=0, result='undefined'
===*/

static duk_ret_t test_1(duk_context *ctx) {
printf("%ld\n", (long) duk_is_primitive(ctx, -1));

printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}

static duk_ret_t test_2(duk_context *ctx) {
printf("%ld\n", (long) duk_is_primitive(ctx, DUK_INVALID_INDEX));

printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}

static duk_ret_t test_3(duk_context *ctx) {
duk_push_null(ctx);

printf("%ld\n", (long) duk_is_primitive(ctx, 0)); /* valid */
printf("%ld\n", (long) duk_is_primitive(ctx, 1)); /* invalid */

printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}

void test(duk_context *ctx) {
TEST_SAFE_CALL(test_1);
TEST_SAFE_CALL(test_2);
TEST_SAFE_CALL(test_3);
}
56 changes: 56 additions & 0 deletions tests/api/test-dev-lightfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,59 @@ static duk_ret_t test_to_pointer(duk_context *ctx) {
return 0;
}

/*===
*** test_is_primitive (duk_safe_call)
is_primitive: 1
final top: 1
==> rc=0, result='undefined'
===*/

/* Because lightfuncs have their own type tag in the C API, they're considered
* a primitive type like plain buffers and pointers. This is also sensible
* because duk_is_object() is 0 for lightfuncs.
*/

static duk_ret_t test_is_primitive(duk_context *ctx) {
duk_push_c_lightfunc(ctx, my_dummy_func, 0, 0, 0);
printf("is_primitive: %ld\n", (long) duk_is_primitive(ctx, -1));

printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}

/*===
*** test_is_object (duk_safe_call)
is_object: 0
final top: 1
==> rc=0, result='undefined'
===*/

/* Lightfuncs are not objects (they're primitive). */

static duk_ret_t test_is_object(duk_context *ctx) {
duk_push_c_lightfunc(ctx, my_dummy_func, 0, 0, 0);
printf("is_object: %ld\n", (long) duk_is_object(ctx, -1));

printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}
/*===
*** test_is_object_coercible (duk_safe_call)
is_object_coercible: 1
final top: 1
==> rc=0, result='undefined'
===*/

/* Lightfuncs are object coercible. */

static duk_ret_t test_is_object_coercible(duk_context *ctx) {
duk_push_c_lightfunc(ctx, my_dummy_func, 0, 0, 0);
printf("is_object_coercible: %ld\n", (long) duk_is_object_coercible(ctx, -1));

printf("final top: %ld\n", (long) duk_get_top(ctx));
return 0;
}

/*===
still here
===*/
Expand All @@ -995,6 +1048,9 @@ void test(duk_context *ctx) {
TEST_SAFE_CALL(test_to_object);
TEST_SAFE_CALL(test_to_buffer);
TEST_SAFE_CALL(test_to_pointer);
TEST_SAFE_CALL(test_is_primitive);
TEST_SAFE_CALL(test_is_object);
TEST_SAFE_CALL(test_is_object_coercible);

printf("still here\n");
fflush(stdout);
Expand Down
51 changes: 28 additions & 23 deletions tests/api/test-is-calls.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
/*===
*** test_1 (duk_safe_call)
00: und=1 null=0 noru=1 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=0
01: und=0 null=1 noru=1 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=0
02: und=0 null=0 noru=0 bool=1 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
03: und=0 null=0 noru=0 bool=1 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
04: und=0 null=0 noru=0 bool=0 num=1 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
05: und=0 null=0 noru=0 bool=0 num=1 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
06: und=0 null=0 noru=0 bool=0 num=1 nan=1 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
07: und=0 null=0 noru=0 bool=0 num=1 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
08: und=0 null=0 noru=0 bool=0 num=1 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
09: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=1 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
10: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=1 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
11: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
12: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=1 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
13: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=1 cfun=1 efun=0 bfun=0 call=1 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
14: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=1 cfun=0 efun=1 bfun=0 call=1 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
15: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=1 cfun=0 efun=0 bfun=1 call=1 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
16: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=1 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
17: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=1 dyn=0 fix=1 ext=0 ptr=0 prim=1 objcoerc=1
18: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=1 dyn=1 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
19: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=1 dyn=0 fix=0 ext=1 ptr=0 prim=1 objcoerc=1
20: und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=1 prim=1 objcoerc=1
00: valididx=1 und=1 null=0 noru=1 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=0
01: valididx=1 und=0 null=1 noru=1 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=0
02: valididx=1 und=0 null=0 noru=0 bool=1 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
03: valididx=1 und=0 null=0 noru=0 bool=1 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
04: valididx=1 und=0 null=0 noru=0 bool=0 num=1 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
05: valididx=1 und=0 null=0 noru=0 bool=0 num=1 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
06: valididx=1 und=0 null=0 noru=0 bool=0 num=1 nan=1 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
07: valididx=1 und=0 null=0 noru=0 bool=0 num=1 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
08: valididx=1 und=0 null=0 noru=0 bool=0 num=1 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
09: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=1 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
10: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=1 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
11: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
12: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=1 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
13: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=1 cfun=1 efun=0 bfun=0 call=1 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
14: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=1 cfun=0 efun=1 bfun=0 call=1 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
15: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=1 cfun=0 efun=0 bfun=1 call=1 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
16: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=1 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=1 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=1
17: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=1 dyn=0 fix=1 ext=0 ptr=0 prim=1 objcoerc=1
18: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=1 dyn=1 fix=0 ext=0 ptr=0 prim=1 objcoerc=1
19: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=1 dyn=0 fix=0 ext=1 ptr=0 prim=1 objcoerc=1
20: valididx=1 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=1 prim=1 objcoerc=1
21: valididx=0 und=0 null=0 noru=0 bool=0 num=0 nan=0 str=0 obj=0 arr=0 fun=0 cfun=0 efun=0 bfun=0 call=0 thr=0 buf=0 dyn=0 fix=0 ext=0 ptr=0 prim=0 objcoerc=0
==> rc=0, result='undefined'
===*/

Expand Down Expand Up @@ -104,11 +105,15 @@ static duk_ret_t test_1(duk_context *ctx) {

/*
* call checkers for each
*
* intentionally overstep by one to see what each returns for an
* invalid index
*/

n = duk_get_top(ctx);
for (i = 0; i < n; i++) {
printf("%02ld: ", (long) i);
for (i = 0; i <= n; i++) {
printf("%02ld:", (long) i);
printf(" valididx=%d", (int) duk_is_valid_index(ctx, i));
printf(" und=%d", (int) duk_is_undefined(ctx, i));
printf(" null=%d", (int) duk_is_null(ctx, i));
printf(" noru=%d", (int) duk_is_null_or_undefined(ctx, i));
Expand Down

0 comments on commit ebef1ee

Please sign in to comment.