diff options
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 19 |
1 files changed, 11 insertions, 8 deletions
@@ -3303,7 +3303,7 @@ rb_str_succ(VALUE orig) VALUE str; char *sbeg, *s, *e, *last_alnum = 0; int c = -1; - long l; + long l, slen; char carry[ONIGENC_CODE_TO_MBC_MAXLEN] = "\1"; long carry_pos = 0, carry_len = 1; enum neighbor_char neighbor = NEIGHBOR_FOUND; @@ -3311,11 +3311,12 @@ rb_str_succ(VALUE orig) str = rb_str_new_with_class(orig, RSTRING_PTR(orig), RSTRING_LEN(orig)); rb_enc_cr_str_copy_for_substr(str, orig); OBJ_INFECT(str, orig); - if (RSTRING_LEN(str) == 0) return str; + slen = RSTRING_LEN(str); + if (slen == 0) return str; enc = STR_ENC_GET(orig); sbeg = RSTRING_PTR(str); - s = e = sbeg + RSTRING_LEN(str); + s = e = sbeg + slen; while ((s = rb_enc_prev_char(sbeg, s, e, enc)) != 0) { if (neighbor == NEIGHBOR_NOT_CHAR && last_alnum) { @@ -3374,12 +3375,14 @@ rb_str_succ(VALUE orig) carry_pos = s - sbeg; } } - RESIZE_CAPA(str, RSTRING_LEN(str) + carry_len); - s = RSTRING_PTR(str) + carry_pos; - memmove(s + carry_len, s, RSTRING_LEN(str) - carry_pos); + RESIZE_CAPA(str, slen + carry_len); + sbeg = RSTRING_PTR(str); + s = sbeg + carry_pos; + memmove(s + carry_len, s, slen - carry_pos); memmove(s, carry, carry_len); - STR_SET_LEN(str, RSTRING_LEN(str) + carry_len); - RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0'; + slen += carry_len; + STR_SET_LEN(str, slen); + sbeg[slen] = '\0'; rb_enc_str_coderange(str); return str; } |