mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
parse.y: junk sigil only names
* parse.y (intern_str): sigil only names are junk, at least one identifier character is needed. [ruby-dev:47723] [Bug #8928] * parse.y (rb_enc_symname_type): fix out of bound access. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42988 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
035917adc1
commit
aba824fece
6 changed files with 155 additions and 1 deletions
|
@ -1,3 +1,10 @@
|
|||
Fri Sep 20 15:01:46 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* parse.y (intern_str): sigil only names are junk, at least one
|
||||
identifier character is needed. [ruby-dev:47723] [Bug #8928]
|
||||
|
||||
* parse.y (rb_enc_symname_type): fix out of bound access.
|
||||
|
||||
Fri Sep 20 14:14:32 2013 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* ext/-test-/printf/printf.c (printf_test_call): Fix an end of buffer
|
||||
|
|
34
ext/-test-/symbol/type.c
Normal file
34
ext/-test-/symbol/type.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include "ruby.h"
|
||||
|
||||
#ifdef HAVE_RB_IS_CONST_NAME
|
||||
# define get_symbol_type(type, t, name) do { \
|
||||
ID id = rb_check_id(&name); \
|
||||
t = (id ? rb_is_##type##_id(id) : rb_is_##type##_name(name)); \
|
||||
} while (0)
|
||||
#else
|
||||
# define get_symbol_type(type, t, name) do { \
|
||||
t = rb_is_##type##_id(rb_to_id(name)); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define define_symbol_type_p(type) \
|
||||
static VALUE \
|
||||
bug_sym_##type##_p(VALUE self, VALUE name) \
|
||||
{ \
|
||||
int t; \
|
||||
get_symbol_type(type, t, name); \
|
||||
return (t ? Qtrue : Qfalse); \
|
||||
}
|
||||
|
||||
#define declare_symbol_type_p(type) \
|
||||
rb_define_singleton_method(klass, #type"?", bug_sym_##type##_p, 1);
|
||||
|
||||
#define FOREACH_ID_TYPES(x) x(const) x(class) x(global) x(instance) x(attrset) x(local) x(junk)
|
||||
|
||||
FOREACH_ID_TYPES(define_symbol_type_p)
|
||||
|
||||
void
|
||||
Init_type(VALUE klass)
|
||||
{
|
||||
FOREACH_ID_TYPES(declare_symbol_type_p)
|
||||
}
|
9
parse.y
9
parse.y
|
@ -10367,6 +10367,7 @@ rb_enc_symname_type(const char *name, long len, rb_encoding *enc, unsigned int a
|
|||
if (m >= e || (*m != '_' && !rb_enc_isalpha(*m, enc) && ISASCII(*m)))
|
||||
return -1;
|
||||
while (m < e && is_identchar(m, e, enc)) m += rb_enc_mbclen(m, e, enc);
|
||||
if (m >= e) break;
|
||||
switch (*m) {
|
||||
case '!': case '?':
|
||||
if (type == ID_GLOBAL || type == ID_CLASS || type == ID_INSTANCE) return -1;
|
||||
|
@ -10484,7 +10485,8 @@ intern_str(VALUE str)
|
|||
enc = rb_enc_get(str);
|
||||
symenc = enc;
|
||||
|
||||
if (rb_cString && !rb_enc_asciicompat(enc)) {
|
||||
if (!len || (rb_cString && !rb_enc_asciicompat(enc))) {
|
||||
junk:
|
||||
id = ID_JUNK;
|
||||
goto new_id;
|
||||
}
|
||||
|
@ -10492,6 +10494,7 @@ intern_str(VALUE str)
|
|||
id = 0;
|
||||
switch (*m) {
|
||||
case '$':
|
||||
if (len < 2) goto junk;
|
||||
id |= ID_GLOBAL;
|
||||
if ((mb = is_special_global_name(++m, e, enc)) != 0) {
|
||||
if (!--mb) symenc = rb_usascii_encoding();
|
||||
|
@ -10500,10 +10503,12 @@ intern_str(VALUE str)
|
|||
break;
|
||||
case '@':
|
||||
if (m[1] == '@') {
|
||||
if (len < 3) goto junk;
|
||||
m++;
|
||||
id |= ID_CLASS;
|
||||
}
|
||||
else {
|
||||
if (len < 2) goto junk;
|
||||
id |= ID_INSTANCE;
|
||||
}
|
||||
m++;
|
||||
|
@ -10530,6 +10535,8 @@ intern_str(VALUE str)
|
|||
}
|
||||
if (name[last] == '=') {
|
||||
/* attribute assignment */
|
||||
if (!rb_enc_symname2_p(name, last, enc))
|
||||
goto junk;
|
||||
id = rb_intern3(name, last, enc);
|
||||
if (id > tLAST_OP_ID && !is_attrset_id(id)) {
|
||||
enc = rb_enc_get(rb_id2str(id));
|
||||
|
|
96
test/-ext-/symbol/test_type.rb
Normal file
96
test/-ext-/symbol/test_type.rb
Normal file
|
@ -0,0 +1,96 @@
|
|||
require 'test/unit'
|
||||
require "-test-/symbol"
|
||||
|
||||
module Test_Symbol
|
||||
class TestType < Test::Unit::TestCase
|
||||
def assert_symtype(sym, pred, msg = nil)
|
||||
assert_send([Bug::Symbol, pred, sym], msg)
|
||||
end
|
||||
|
||||
def assert_not_symtype(sym, pred, msg = nil)
|
||||
assert_not_send([Bug::Symbol, pred, sym], msg)
|
||||
end
|
||||
|
||||
def test_const
|
||||
assert_symtype("Foo", :const?)
|
||||
assert_not_symtype("F!", :const?)
|
||||
assert_not_symtype("foo", :const?)
|
||||
assert_not_symtype("@foo", :const?)
|
||||
assert_not_symtype("@@foo", :const?)
|
||||
assert_not_symtype("$foo", :const?)
|
||||
assert_not_symtype("foo=", :const?)
|
||||
assert_not_symtype("[foo]", :const?)
|
||||
assert_not_symtype("xFoo", :const?)
|
||||
end
|
||||
|
||||
def test_local
|
||||
assert_symtype("foo", :local?)
|
||||
assert_symtype("fooBar", :local?)
|
||||
assert_symtype("foo_bar", :local?)
|
||||
assert_not_symtype("foo!", :local?)
|
||||
assert_not_symtype("foo?", :local?)
|
||||
assert_not_symtype("Foo", :local?)
|
||||
assert_not_symtype("@foo", :local?)
|
||||
assert_not_symtype("@@foo", :local?)
|
||||
assert_not_symtype("$foo", :local?)
|
||||
assert_not_symtype("foo=", :local?)
|
||||
assert_not_symtype("[foo]", :local?)
|
||||
end
|
||||
|
||||
def test_global
|
||||
assert_symtype("$foo", :global?)
|
||||
assert_symtype("$$", :global?)
|
||||
assert_not_symtype("$()", :global?)
|
||||
assert_not_symtype("$", :global?)
|
||||
assert_not_symtype("foo", :global?)
|
||||
assert_not_symtype("Foo", :global?)
|
||||
assert_not_symtype("@foo", :global?)
|
||||
assert_not_symtype("@@foo", :global?)
|
||||
assert_not_symtype("foo=", :global?)
|
||||
assert_not_symtype("[foo]", :global?)
|
||||
end
|
||||
|
||||
def test_instance
|
||||
assert_symtype("@foo", :instance?)
|
||||
assert_not_symtype("@", :instance?)
|
||||
assert_not_symtype("@1", :instance?)
|
||||
assert_not_symtype("@@", :instance?)
|
||||
assert_not_symtype("foo", :instance?)
|
||||
assert_not_symtype("Foo", :instance?)
|
||||
assert_not_symtype("@@foo", :instance?)
|
||||
assert_not_symtype("$foo", :instance?)
|
||||
assert_not_symtype("foo=", :instance?)
|
||||
assert_not_symtype("[foo]", :instance?)
|
||||
end
|
||||
|
||||
def test_class
|
||||
assert_symtype("@@foo", :class?)
|
||||
assert_not_symtype("@@", :class?)
|
||||
assert_not_symtype("@", :class?)
|
||||
assert_not_symtype("@@1", :class?)
|
||||
assert_not_symtype("foo", :class?)
|
||||
assert_not_symtype("Foo", :class?)
|
||||
assert_not_symtype("@foo", :class?)
|
||||
assert_not_symtype("$foo", :class?)
|
||||
assert_not_symtype("foo=", :class?)
|
||||
assert_not_symtype("[foo]", :class?)
|
||||
end
|
||||
|
||||
def test_attrset
|
||||
assert_symtype("foo=", :attrset?)
|
||||
assert_symtype("Foo=", :attrset?)
|
||||
assert_symtype("@foo=", :attrset?)
|
||||
assert_symtype("@@foo=", :attrset?)
|
||||
assert_symtype("$foo=", :attrset?)
|
||||
assert_not_symtype("0=", :attrset?)
|
||||
assert_not_symtype("@=", :attrset?)
|
||||
assert_not_symtype("@@=", :attrset?)
|
||||
assert_not_symtype("foo", :attrset?)
|
||||
assert_not_symtype("Foo", :attrset?)
|
||||
assert_not_symtype("@foo", :attrset?)
|
||||
assert_not_symtype("@@foo", :attrset?)
|
||||
assert_not_symtype("$foo", :attrset?)
|
||||
assert_not_symtype("[foo]", :attrset?)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -688,6 +688,7 @@ class TestModule < Test::Unit::TestCase
|
|||
c.class_eval('@@foo = :foo')
|
||||
assert_equal(:foo, c.class_variable_get(:@@foo))
|
||||
assert_raise(NameError) { c.class_variable_get(:@@bar) } # c.f. instance_variable_get
|
||||
assert_raise(NameError) { c.class_variable_get(:'@@') }
|
||||
assert_raise(NameError) { c.class_variable_get('@@') }
|
||||
assert_raise(NameError) { c.class_variable_get(:foo) }
|
||||
assert_raise(NameError) { c.class_variable_get("bar") }
|
||||
|
@ -704,6 +705,7 @@ class TestModule < Test::Unit::TestCase
|
|||
c = Class.new
|
||||
c.class_variable_set(:@@foo, :foo)
|
||||
assert_equal(:foo, c.class_eval('@@foo'))
|
||||
assert_raise(NameError) { c.class_variable_set(:'@@', 1) }
|
||||
assert_raise(NameError) { c.class_variable_set('@@', 1) }
|
||||
assert_raise(NameError) { c.class_variable_set(:foo, 1) }
|
||||
assert_raise(NameError) { c.class_variable_set("bar", 1) }
|
||||
|
@ -722,6 +724,8 @@ class TestModule < Test::Unit::TestCase
|
|||
c.class_eval('@@foo = :foo')
|
||||
assert_equal(true, c.class_variable_defined?(:@@foo))
|
||||
assert_equal(false, c.class_variable_defined?(:@@bar))
|
||||
assert_raise(NameError) { c.class_variable_defined?(:'@@') }
|
||||
assert_raise(NameError) { c.class_variable_defined?('@@') }
|
||||
assert_raise(NameError) { c.class_variable_defined?(:foo) }
|
||||
assert_raise(NameError) { c.class_variable_defined?("bar") }
|
||||
assert_raise(TypeError) { c.class_variable_defined?(1) }
|
||||
|
|
|
@ -163,6 +163,8 @@ class TestObject < Test::Unit::TestCase
|
|||
o.instance_eval { @foo = :foo }
|
||||
assert_equal(:foo, o.instance_variable_get(:@foo))
|
||||
assert_equal(nil, o.instance_variable_get(:@bar))
|
||||
assert_raise(NameError) { o.instance_variable_get('@') }
|
||||
assert_raise(NameError) { o.instance_variable_get(:'@') }
|
||||
assert_raise(NameError) { o.instance_variable_get(:foo) }
|
||||
assert_raise(NameError) { o.instance_variable_get("bar") }
|
||||
assert_raise(TypeError) { o.instance_variable_get(1) }
|
||||
|
@ -178,6 +180,8 @@ class TestObject < Test::Unit::TestCase
|
|||
o = Object.new
|
||||
o.instance_variable_set(:@foo, :foo)
|
||||
assert_equal(:foo, o.instance_eval { @foo })
|
||||
assert_raise(NameError) { o.instance_variable_set(:'@', 1) }
|
||||
assert_raise(NameError) { o.instance_variable_set('@', 1) }
|
||||
assert_raise(NameError) { o.instance_variable_set(:foo, 1) }
|
||||
assert_raise(NameError) { o.instance_variable_set("bar", 1) }
|
||||
assert_raise(TypeError) { o.instance_variable_set(1, 1) }
|
||||
|
@ -195,6 +199,8 @@ class TestObject < Test::Unit::TestCase
|
|||
o.instance_eval { @foo = :foo }
|
||||
assert_equal(true, o.instance_variable_defined?(:@foo))
|
||||
assert_equal(false, o.instance_variable_defined?(:@bar))
|
||||
assert_raise(NameError) { o.instance_variable_defined?(:'@') }
|
||||
assert_raise(NameError) { o.instance_variable_defined?('@') }
|
||||
assert_raise(NameError) { o.instance_variable_defined?(:foo) }
|
||||
assert_raise(NameError) { o.instance_variable_defined?("bar") }
|
||||
assert_raise(TypeError) { o.instance_variable_defined?(1) }
|
||||
|
|
Loading…
Reference in a new issue