parse.y: ignore constant name captures

* parse.y (reg_named_capture_assign_iter): ignore non-local name
  captures, including non-ASCII constant names.
  [ruby-dev:50719] [Bug #15437]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66463 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2018-12-20 05:43:15 +00:00
Родитель 766f9b4aff
Коммит f89238ec0d
4 изменённых файлов: 14 добавлений и 5 удалений

Просмотреть файл

@ -10669,11 +10669,12 @@ reg_named_capture_assign_iter(const OnigUChar *name, const OnigUChar *name_end,
ID var;
NODE *node, *succ;
if (!len || (*name != '_' && ISASCII(*name) && !rb_enc_islower(*name, enc)) ||
(len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) ||
!rb_enc_symname2_p(s, len, enc)) {
if (!len) return ST_CONTINUE;
if (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len))
return ST_CONTINUE;
}
if (rb_enc_symname_type(s, len, enc, (1U<<ID_LOCAL)) != ID_LOCAL)
return ST_CONTINUE;
var = intern_cstr(s, len, enc);
node = node_assign(p, assignable(p, var, 0, arg->loc), NEW_LIT(ID2SYM(var), arg->loc), arg->loc);
succ = arg->succ_block;

Просмотреть файл

@ -238,7 +238,7 @@ rb_sym_constant_char_p(const char *name, long nlen, rb_encoding *enc)
#define IDSET_ATTRSET_FOR_SYNTAX ((1U<<ID_LOCAL)|(1U<<ID_CONST))
#define IDSET_ATTRSET_FOR_INTERN (~(~0U<<(1<<ID_SCOPE_SHIFT)) & ~(1U<<ID_ATTRSET))
static int
int
rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_attrset)
{
const char *m = name;

Просмотреть файл

@ -98,6 +98,8 @@ is_global_name_punct(const int c)
return (ruby_global_name_punct_bits[(c - 0x20) / 32] >> (c % 32)) & 1;
}
int rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int allowed_attrset);
RUBY_SYMBOL_EXPORT_BEGIN
size_t rb_sym_immortal_count(void);

Просмотреть файл

@ -216,6 +216,12 @@ class TestRegexp < Test::Unit::TestCase
assert_not_include(local_variables, :nil, "[ruby-dev:32675]")
end
def test_assign_named_capture_to_const
%W[C \u{1d402}].each do |name|
assert_equal(:ok, Class.new.class_eval("#{name} = :ok; /(?<#{name}>.*)/ =~ 'ng'; #{name}"))
end
end
def test_assign_named_capture_trace
bug = '[ruby-core:79940] [Bug #13287]'
assert_normal_exit("#{<<-"begin;"}\n#{<<-"end;"}", bug)