summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-28 08:35:48 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-06-28 08:35:48 +0000
commitd0fb73a0f0b82ebc0d3eb931c28686a2b9c40fef (patch)
tree7587165b00fd75037adcd1667a102bda5e9f3d09
parent40efaab3012188e159d0f6e104371c22fc3fcafd (diff)
downloadbundler-d0fb73a0f0b82ebc0d3eb931c28686a2b9c40fef.tar.gz
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
-rw-r--r--encoding.c8
-rw-r--r--include/ruby/encoding.h1
-rw-r--r--marshal.c50
-rw-r--r--spec/ruby/optional/capi/encoding_spec.rb24
4 files changed, 39 insertions, 44 deletions
diff --git a/encoding.c b/encoding.c
index 9744c1d692..8d1894aa91 100644
--- a/encoding.c
+++ b/encoding.c
@@ -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;
diff --git a/include/ruby/encoding.h b/include/ruby/encoding.h
index 0c7e1e3d6a..32d874aa9d 100644
--- a/include/ruby/encoding.h
+++ b/include/ruby/encoding.h
@@ -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);
diff --git a/marshal.c b/marshal.c
index 4cfa2e10dc..365c468e02 100644
--- a/marshal.c
+++ b/marshal.c
@@ -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 {
diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb
index ba31c84f1c..cd3f00d478 100644
--- a/spec/ruby/optional/capi/encoding_spec.rb
+++ b/spec/ruby/optional/capi/encoding_spec.rb
@@ -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