diff options
Diffstat (limited to 'transcode.c')
| -rw-r--r-- | transcode.c | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/transcode.c b/transcode.c index 1c9cc01f36..84c579eb2e 100644 --- a/transcode.c +++ b/transcode.c @@ -9,22 +9,20 @@ **********************************************************************/ -#include "ruby/encoding.h" #include "internal.h" #include "transcode_data.h" #include <ctype.h> -#include "id.h" #define ENABLE_ECONV_NEWLINE_OPTION 1 /* VALUE rb_cEncoding = rb_define_class("Encoding", rb_cObject); */ -static VALUE rb_eUndefinedConversionError; -static VALUE rb_eInvalidByteSequenceError; -static VALUE rb_eConverterNotFoundError; +VALUE rb_eUndefinedConversionError; +VALUE rb_eInvalidByteSequenceError; +VALUE rb_eConverterNotFoundError; VALUE rb_cEncodingConverter; -static VALUE sym_invalid, sym_undef, sym_replace, sym_fallback; +static VALUE sym_invalid, sym_undef, sym_replace, sym_fallback, sym_aref; static VALUE sym_xml, sym_text, sym_attr; static VALUE sym_universal_newline; static VALUE sym_crlf_newline; @@ -370,12 +368,14 @@ load_transcoder_entry(transcoder_entry_t *entry) const size_t total_len = sizeof(transcoder_lib_prefix) - 1 + len; const VALUE fn = rb_str_new(0, total_len); char *const path = RSTRING_PTR(fn); + const int safe = rb_safe_level(); memcpy(path, transcoder_lib_prefix, sizeof(transcoder_lib_prefix) - 1); memcpy(path + sizeof(transcoder_lib_prefix) - 1, lib, len); rb_str_set_len(fn, total_len); + FL_UNSET(fn, FL_TAINT); OBJ_FREEZE(fn); - rb_require_string(fn); + rb_require_safe(fn, safe > 3 ? 3 : safe); } if (entry->transcoder) @@ -974,10 +974,21 @@ rb_econv_open0(const char *sname, const char *dname, int ecflags) int num_trans; rb_econv_t *ec; - /* Just check if sname and dname are defined */ - /* (This check is needed?) */ - if (*sname) rb_enc_find_index(sname); - if (*dname) rb_enc_find_index(dname); + int sidx, didx; + + if (*sname) { + sidx = rb_enc_find_index(sname); + if (0 <= sidx) { + rb_enc_from_index(sidx); + } + } + + if (*dname) { + didx = rb_enc_find_index(dname); + if (0 <= didx) { + rb_enc_from_index(didx); + } + } if (*sname == '\0' && *dname == '\0') { num_trans = 0; @@ -1183,6 +1194,7 @@ rb_trans_conv(rb_econv_t *ec, if (ec->elems[0].last_result == econv_after_output) ec->elems[0].last_result = econv_source_buffer_empty; + needreport_index = -1; for (i = ec->num_trans-1; 0 <= i; i--) { switch (ec->elems[i].last_result) { case econv_invalid_byte_sequence: @@ -1191,6 +1203,7 @@ rb_trans_conv(rb_econv_t *ec, case econv_after_output: case econv_finished: sweep_start = i+1; + needreport_index = i; goto found_needreport; case econv_destination_buffer_full: @@ -1841,6 +1854,7 @@ rb_econv_substr_append(rb_econv_t *ec, VALUE src, long off, long len, VALUE dst, src = rb_str_new_frozen(src); dst = rb_econv_append(ec, RSTRING_PTR(src) + off, len, dst, flags); RB_GC_GUARD(src); + OBJ_INFECT_RAW(dst, src); return dst; } @@ -2242,7 +2256,7 @@ method_fallback(VALUE fallback, VALUE c) static VALUE aref_fallback(VALUE fallback, VALUE c) { - return rb_funcallv_public(fallback, idAREF, 1, &c); + return rb_funcall3(fallback, sym_aref, 1, &c); } static void @@ -2536,7 +2550,7 @@ rb_econv_prepare_options(VALUE opthash, VALUE *opts, int ecflags) if (!NIL_P(v)) { VALUE h = rb_check_hash_type(v); if (NIL_P(h) - ? (rb_obj_is_proc(v) || rb_obj_is_method(v) || rb_respond_to(v, idAREF)) + ? (rb_obj_is_proc(v) || rb_obj_is_method(v) || rb_respond_to(v, sym_aref)) : (v = h, 1)) { if (NIL_P(newhash)) newhash = rb_hash_new(); @@ -2891,11 +2905,6 @@ encoded_dup(VALUE newstr, VALUE str, int encidx) return str_encode_associate(newstr, encidx); } -/* - * Document-class: Encoding::Converter - * - * Encoding conversion class. - */ static void econv_free(void *ptr) { @@ -3142,10 +3151,10 @@ econv_s_search_convpath(int argc, VALUE *argv, VALUE klass) transcode_search_path(sname, dname, search_convpath_i, &convpath); if (NIL_P(convpath)) { - VALUE exc = rb_econv_open_exc(sname, dname, ecflags); - RB_GC_GUARD(snamev); - RB_GC_GUARD(dnamev); - rb_exc_raise(exc); + VALUE exc = rb_econv_open_exc(sname, dname, ecflags); + RB_GC_GUARD(snamev); + RB_GC_GUARD(dnamev); + rb_exc_raise(exc); } if (decorate_convpath(convpath, ecflags) == -1) { @@ -3779,6 +3788,7 @@ econv_primitive_convert(int argc, VALUE *argv, VALUE self) res = rb_econv_convert(ec, &ip, is, &op, os, flags); rb_str_set_len(output, op-(unsigned char *)RSTRING_PTR(output)); if (!NIL_P(input)) { + OBJ_INFECT_RAW(output, input); rb_str_drop_bytes(input, ip - (unsigned char *)RSTRING_PTR(input)); } @@ -4069,7 +4079,7 @@ econv_insert_output(VALUE self, VALUE string) } /* - * call-seq: + * call-seq * ec.putback -> string * ec.putback(max_numbytes) -> string * @@ -4100,9 +4110,10 @@ econv_putback(int argc, VALUE *argv, VALUE self) int putbackable; VALUE str, max; - if (!rb_check_arity(argc, 0, 1) || NIL_P(max = argv[0])) { + rb_scan_args(argc, argv, "01", &max); + + if (NIL_P(max)) n = rb_econv_putbackable(ec); - } else { n = NUM2INT(max); putbackable = rb_econv_putbackable(ec); @@ -4409,6 +4420,7 @@ Init_transcode(void) sym_undef = ID2SYM(rb_intern("undef")); sym_replace = ID2SYM(rb_intern("replace")); sym_fallback = ID2SYM(rb_intern("fallback")); + sym_aref = ID2SYM(rb_intern("[]")); sym_xml = ID2SYM(rb_intern("xml")); sym_text = ID2SYM(rb_intern("text")); sym_attr = ID2SYM(rb_intern("attr")); |
