1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

check enc_capable.

* encoding.c (rb_enc_capable): make it extern to check enc_capable.
  enc_index can be set to limited types such as T_STRING, T_REGEX
  and so on. This function check an object is this kind of types.

* include/ruby/encoding.h: ditto.

* encoding.c (enc_set_index): check a given object is enc_capable.

* include/ruby/encoding.h (PUREFUNC):

* marshal.c (encoding_name): check `rb_enc_capable` first.

* marshal.c (r_ivar): ditto. If it is not enc_capable, it should be
  malformed data.

* spec/ruby/optional/capi/encoding_spec.rb: remove tests depending
  on the wrong feature: all objects can set enc_index.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63777 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2018-06-28 08:35:48 +00:00
parent 40efaab301
commit d0fb73a0f0
4 changed files with 39 additions and 44 deletions

View file

@ -756,6 +756,12 @@ enc_capable(VALUE obj)
}
}
int
rb_enc_capable(VALUE obj)
{
return enc_capable(obj);
}
ID
rb_id_encoding(void)
{
@ -813,6 +819,8 @@ rb_enc_get_index(VALUE obj)
static void
enc_set_index(VALUE obj, int idx)
{
if (!enc_capable(obj)) rb_bug("enc_set_index: not capable object");
if (idx < ENCODING_INLINE_MAX) {
ENCODING_SET_INLINED(obj, idx);
return;

View file

@ -122,6 +122,7 @@ PUREFUNC(int rb_enc_dummy_p(rb_encoding *enc));
PUREFUNC(int rb_enc_to_index(rb_encoding *enc));
int rb_enc_get_index(VALUE obj);
void rb_enc_set_index(VALUE obj, int encindex);
int rb_enc_capable(VALUE obj);
int rb_enc_find_index(const char *name);
int rb_to_encoding_index(VALUE);
rb_encoding *rb_to_encoding(VALUE);

View file

@ -578,29 +578,34 @@ obj_count_ivars(st_data_t key, st_data_t val, st_data_t a)
static VALUE
encoding_name(VALUE obj, struct dump_arg *arg)
{
int encidx = rb_enc_get_index(obj);
rb_encoding *enc = 0;
st_data_t name;
if (rb_enc_capable(obj)) {
int encidx = rb_enc_get_index(obj);
rb_encoding *enc = 0;
st_data_t name;
if (encidx <= 0 || !(enc = rb_enc_from_index(encidx))) {
return Qnil;
}
if (encidx <= 0 || !(enc = rb_enc_from_index(encidx))) {
return Qnil;
}
/* special treatment for US-ASCII and UTF-8 */
if (encidx == rb_usascii_encindex()) {
return Qfalse;
}
else if (encidx == rb_utf8_encindex()) {
return Qtrue;
}
/* special treatment for US-ASCII and UTF-8 */
if (encidx == rb_usascii_encindex()) {
return Qfalse;
}
else if (encidx == rb_utf8_encindex()) {
return Qtrue;
}
if (arg->encodings ?
!st_lookup(arg->encodings, (st_data_t)rb_enc_name(enc), &name) :
(arg->encodings = st_init_strcasetable(), 1)) {
name = (st_data_t)rb_str_new_cstr(rb_enc_name(enc));
st_insert(arg->encodings, (st_data_t)rb_enc_name(enc), name);
if (arg->encodings ?
!st_lookup(arg->encodings, (st_data_t)rb_enc_name(enc), &name) :
(arg->encodings = st_init_strcasetable(), 1)) {
name = (st_data_t)rb_str_new_cstr(rb_enc_name(enc));
st_insert(arg->encodings, (st_data_t)rb_enc_name(enc), name);
}
return (VALUE)name;
}
else {
return Qnil;
}
return (VALUE)name;
}
static void
@ -1486,7 +1491,12 @@ r_ivar(VALUE obj, int *has_encoding, struct load_arg *arg)
VALUE val = r_object(arg);
int idx = sym2encidx(sym, val);
if (idx >= 0) {
rb_enc_associate_index(obj, idx);
if (rb_enc_capable(obj)) {
rb_enc_associate_index(obj, idx);
}
else {
rb_raise(rb_eArgError, "%"PRIsVALUE" is not enc_capable", obj);
}
if (has_encoding) *has_encoding = TRUE;
}
else {

View file

@ -12,24 +12,6 @@ describe :rb_enc_get_index, shared: true do
it "returns the index of the encoding of a Regexp" do
@s.send(@method, /regexp/).should >= 0
end
it "returns the index of the encoding of an Object" do
obj = mock("rb_enc_get_index string")
@s.rb_enc_set_index(obj, 1)
@s.send(@method, obj).should == 1
end
it "returns the index of the dummy encoding of an Object" do
obj = mock("rb_enc_get_index string")
index = Encoding.list.index(Encoding::UTF_16)
@s.rb_enc_set_index(obj, index)
@s.send(@method, obj).should == index
end
it "returns 0 for an object without an encoding" do
obj = mock("rb_enc_get_index string")
@s.send(@method, obj).should == 0
end
end
describe :rb_enc_set_index, shared: true do
@ -48,12 +30,6 @@ describe :rb_enc_set_index, shared: true do
result = @s.send(@method, str, 1)
result.first.should == result.last
end
it "associates an encoding with an object" do
obj = mock("rb_enc_set_index string")
result = @s.send(@method, obj, 1)
result.first.should == result.last
end
end
describe "C-API Encoding function" do