Fix assert fail if object literal key is not a string (fix #953)
This commit is contained in:
1 parent
83ab4e273b
commit
154d0ee4a8
5 files changed
+455
-399
No files matched your search
@@ -595,6 +595,10 @@ block gen_const_object(block expr) {
|
|||||||
is_const = 0;
|
is_const = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (jv_get_kind(k) != JV_KIND_STRING) {
|
||||||
|
is_const = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
o = jv_object_set(o, k, v);
|
o = jv_object_set(o, k, v);
|
||||||
k = jv_null();
|
k = jv_null();
|
||||||
v = jv_null();
|
v = jv_null();
|
||||||
|
|||||||
+414
-392
File diff suppressed because it is too large.
Load diff
+7
-7
@@ -30,8 +30,8 @@
|
|||||||
This special exception was added by the Free Software Foundation in
|
This special exception was added by the Free Software Foundation in
|
||||||
version 2.2 of Bison. */
|
version 2.2 of Bison. */
|
||||||
|
|
||||||
#ifndef YY_YY_PARSER_H_INCLUDED
|
#ifndef YY_YY_SRC_PARSER_H_INCLUDED
|
||||||
# define YY_YY_PARSER_H_INCLUDED
|
# define YY_YY_SRC_PARSER_H_INCLUDED
|
||||||
/* Debug traces. */
|
/* Debug traces. */
|
||||||
#ifndef YYDEBUG
|
#ifndef YYDEBUG
|
||||||
# define YYDEBUG 0
|
# define YYDEBUG 0
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
extern int yydebug;
|
extern int yydebug;
|
||||||
#endif
|
#endif
|
||||||
/* "%code requires" blocks. */
|
/* "%code requires" blocks. */
|
||||||
#line 11 "parser.y" /* yacc.c:1909 */
|
#line 11 "src/parser.y" /* yacc.c:1909 */
|
||||||
|
|
||||||
#include "locfile.h"
|
#include "locfile.h"
|
||||||
struct lexer_param;
|
struct lexer_param;
|
||||||
@@ -57,7 +57,7 @@ struct lexer_param;
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#line 61 "parser.h" /* yacc.c:1909 */
|
#line 61 "src/parser.h" /* yacc.c:1909 */
|
||||||
|
|
||||||
/* Token type. */
|
/* Token type. */
|
||||||
#ifndef YYTOKENTYPE
|
#ifndef YYTOKENTYPE
|
||||||
@@ -161,12 +161,12 @@ struct lexer_param;
|
|||||||
typedef union YYSTYPE YYSTYPE;
|
typedef union YYSTYPE YYSTYPE;
|
||||||
union YYSTYPE
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
#line 31 "parser.y" /* yacc.c:1909 */
|
#line 31 "src/parser.y" /* yacc.c:1909 */
|
||||||
|
|
||||||
jv literal;
|
jv literal;
|
||||||
block blk;
|
block blk;
|
||||||
|
|
||||||
#line 170 "parser.h" /* yacc.c:1909 */
|
#line 170 "src/parser.h" /* yacc.c:1909 */
|
||||||
};
|
};
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
@@ -190,4 +190,4 @@ struct YYLTYPE
|
|||||||
|
|
||||||
int yyparse (block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr);
|
int yyparse (block* answer, int* errors, struct locfile* locations, struct lexer_param* lexer_param_ptr);
|
||||||
|
|
||||||
#endif /* !YY_YY_PARSER_H_INCLUDED */
|
#endif /* !YY_YY_SRC_PARSER_H_INCLUDED */
|
||||||
@@ -164,6 +164,18 @@ int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, block* answer, int* errors,
|
|||||||
return tok;
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns string message if the block is a constant that is not valid as an
|
||||||
|
* object key. */
|
||||||
|
static jv check_object_key(block k) {
|
||||||
|
if (block_is_const(k) && block_const_kind(k) != JV_KIND_STRING) {
|
||||||
|
char errbuf[15];
|
||||||
|
return jv_string_fmt("Cannot use %s (%s) as object key",
|
||||||
|
jv_kind_name(block_const_kind(k)),
|
||||||
|
jv_dump_string_trunc(jv_copy(block_const(k)), errbuf, sizeof(errbuf)));
|
||||||
|
}
|
||||||
|
return jv_invalid();
|
||||||
|
}
|
||||||
|
|
||||||
static block gen_dictpair(block k, block v) {
|
static block gen_dictpair(block k, block v) {
|
||||||
return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT));
|
return BLOCK(gen_subexp(k), gen_subexp(v), gen_op_simple(INSERT));
|
||||||
}
|
}
|
||||||
@@ -808,6 +820,11 @@ String ':' Pattern {
|
|||||||
$$ = gen_object_matcher($1, $3);
|
$$ = gen_object_matcher($1, $3);
|
||||||
} |
|
} |
|
||||||
'(' Exp ')' ':' Pattern {
|
'(' Exp ')' ':' Pattern {
|
||||||
|
jv msg = check_object_key($2);
|
||||||
|
if (jv_is_valid(msg)) {
|
||||||
|
FAIL(@$, jv_string_value(msg));
|
||||||
|
}
|
||||||
|
jv_free(msg);
|
||||||
$$ = gen_object_matcher($2, $5);
|
$$ = gen_object_matcher($2, $5);
|
||||||
} |
|
} |
|
||||||
error ':' Pattern {
|
error ':' Pattern {
|
||||||
@@ -905,6 +922,11 @@ IDENT ':' ExpD {
|
|||||||
gen_index(gen_noop(), gen_const($1)));
|
gen_index(gen_noop(), gen_const($1)));
|
||||||
}
|
}
|
||||||
| '(' Exp ')' ':' ExpD {
|
| '(' Exp ')' ':' ExpD {
|
||||||
|
jv msg = check_object_key($2);
|
||||||
|
if (jv_is_valid(msg)) {
|
||||||
|
FAIL(@$, jv_string_value(msg));
|
||||||
|
}
|
||||||
|
jv_free(msg);
|
||||||
$$ = gen_dictpair($2, $5);
|
$$ = gen_dictpair($2, $5);
|
||||||
}
|
}
|
||||||
| error ':' ExpD {
|
| error ':' ExpD {
|
||||||
|
|||||||
@@ -105,6 +105,14 @@ null
|
|||||||
{"a":1, "b":2, "c":3, "a$2":4}
|
{"a":1, "b":2, "c":3, "a$2":4}
|
||||||
{"a":1, "b":2, "a$2":4}
|
{"a":1, "b":2, "a$2":4}
|
||||||
|
|
||||||
|
%%FAIL
|
||||||
|
{(0):1}
|
||||||
|
jq: error: Cannot use number (0) as object key at <top-level>, line 1:
|
||||||
|
|
||||||
|
%%FAIL
|
||||||
|
{non_const:., (0):1}
|
||||||
|
jq: error: Cannot use number (0) as object key at <top-level>, line 1:
|
||||||
|
|
||||||
#
|
#
|
||||||
# Field access, piping
|
# Field access, piping
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in new issue
Block a user