summaryrefslogtreecommitdiff
path: root/prism
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2023-11-01 14:28:01 -0400
committergit <svn-admin@ruby-lang.org>2023-11-02 22:14:08 +0000
commitee7bf4643d2716d44e13a732caf588b1a6275f7a (patch)
treea943be03a2f1719a8588b3e6a4d9806a4f09489d /prism
parentc6f5c64639152b950d4d1ccbaa199b621099e2a5 (diff)
[ruby/prism] Handle invalid constants in the constant pool
It's possible for us to parse a constant that is invalid in the current encoding. To fix this, we wrap the intern function in an rb_protect to ensure we always put a valid symbol into the AST. https://github.com/ruby/prism/commit/e78398554d
Diffstat (limited to 'prism')
-rw-r--r--prism/prism.c7
-rw-r--r--prism/templates/ext/prism/api_node.c.erb12
2 files changed, 16 insertions, 3 deletions
diff --git a/prism/prism.c b/prism/prism.c
index 42d9712063..de32ccae63 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -8633,13 +8633,16 @@ parser_lex(pm_parser_t *parser) {
if (!lex_state_beg_p(parser) && match(parser, '=')) {
lex_state_set(parser, PM_LEX_STATE_BEG);
LEX(PM_TOKEN_PERCENT_EQUAL);
- }
- else if(
+ } else if (
lex_state_beg_p(parser) ||
(lex_state_p(parser, PM_LEX_STATE_FITEM) && (peek(parser) == 's')) ||
lex_state_spcarg_p(parser, space_seen)
) {
if (!parser->encoding.alnum_char(parser->current.end, parser->end - parser->current.end)) {
+ if (*parser->current.end >= 0x80) {
+ pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT);
+ }
+
lex_mode_push_string(parser, true, false, lex_mode_incrementor(*parser->current.end), lex_mode_terminator(*parser->current.end));
size_t eol_length = match_eol(parser);
diff --git a/prism/templates/ext/prism/api_node.c.erb b/prism/templates/ext/prism/api_node.c.erb
index 6da5832185..1ffbf6c9f8 100644
--- a/prism/templates/ext/prism/api_node.c.erb
+++ b/prism/templates/ext/prism/api_node.c.erb
@@ -83,7 +83,17 @@ pm_ast_new(pm_parser_t *parser, pm_node_t *node, rb_encoding *encoding) {
for (uint32_t index = 0; index < parser->constant_pool.size; index++) {
pm_constant_t *constant = &parser->constant_pool.constants[index];
- constants[index] = rb_intern3((const char *) constant->start, constant->length, encoding);
+ int state = 0;
+
+ VALUE string = rb_enc_str_new((const char *) constant->start, constant->length, encoding);
+ ID value = rb_protect(rb_intern_str, string, &state);
+
+ if (state != 0) {
+ value = rb_intern_const("?");
+ rb_set_errinfo(Qnil);
+ }
+
+ constants[index] = value;
}
pm_node_stack_node_t *node_stack = NULL;