[Bug:trunk] rubyspec: StringIO#ungetc when passed [char] pads with \000 when the current position i

stringio e$B$N%a%s%F%J$N$J$+$@$5$s!"$b$7$/$O$^$D$b$H$5$se(B
e$B1sF#$G$9!#e(B

stringio e$B$K4X$7$F!"%P%C%U%!=*C<$h$j@h$Ke(B pos e$B$r9g$o$;$?>uBV$Ge(B
StringIO#ungetc e$B$r8F$s$@;~$N5sF0$,e(B 1.8 e$B$He(B 1.9
e$B$G0c$$$^$9!#e(B

1.8 e$B$G$O4V$,e(B \0 e$B$GKd$a$i$l$ke(B

$ ruby18 -rstringio -e ’
io = StringIO.new(“1234”)
io.pos = 15
io.ungetc(?A)
p io.string

“1234\000\000\000\000\000\000\000\000\000\000A”

1.9 e$B$G$ONc30$K$J$ke(B

$ ./ruby -rstringio -e ’
io = StringIO.new(“1234”)
io.pos = 15
io.ungetc(?A)
p io.string

-e:4:in ungetc': index 14 out of string (IndexError) from -e:4:in

r13261 e$B$,860x$N$h$&$G$9!#$3$N5sF0$NJQ99$rA@$C$?$b$N$G$O$J$$e(B
e$B$h$&$J5$$,$7$^$9$,!"$$$+$,$G$7$g$&$+!#e(B

e$B1sF#$G$9!#e(B

2010e$BG/e(B1e$B7ne(B31e$BF|e(B19:21 Yusuke ENDOH [email protected]:


-e:4:in ungetc': index 14 out of string (IndexError) from -e:4:in

r13261 e$B$,860x$N$h$&$G$9!#$3$N5sF0$NJQ99$rA@$C$?$b$N$G$O$J$$e(B
e$B$h$&$J5$$,$7$^$9$,!"$$$+$,$G$7$g$&$+!#e(B

e$B@.@%$5$s$N4F=$$N$b$H!"%Q%C%A$r=q$$$F$$^$7$?!#e(B
e$BH?BP$,$J$1$l$P%3%
%C%H$7$F$7$^$$$^$9!#e(B

diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
index f193c6e…faf974e 100644
— a/ext/stringio/stringio.c
+++ b/ext/stringio/stringio.c
@@ -725,17 +725,26 @@ strio_ungetc(VALUE self, VALUE c)
c = rb_str_conv_enc(c, enc2, enc);
}
}

  • /* get logical position */
  • lpos = 0; p = RSTRING_PTR(ptr->string); pend = p + ptr->pos;
  • for (;:wink: {
  • clen = rb_enc_mbclen(p, pend, enc);
  • if (p+clen >= pend) break;
  • p += clen;
  • lpos++;
  • if (RSTRING_LEN(ptr->string) < ptr->pos) {
  • long len = RSTRING_LEN(ptr->string);
  • rb_str_resize(ptr->string, ptr->pos - 1);
  • memset(RSTRING_PTR(ptr->string) + len, 0, ptr->pos - len - 1);
  • rb_str_concat(ptr->string, c);
  • ptr->pos–;
  • }
  • else {
  • /* get logical position */
  • lpos = 0; p = RSTRING_PTR(ptr->string); pend = p + ptr->pos;
  • for (;:wink: {
  •  clen = rb_enc_mbclen(p, pend, enc);
    
  •  if (p+clen >= pend) break;
    
  •  p += clen;
    
  •  lpos++;
    
  • }
  • clen = p - RSTRING_PTR(ptr->string);
  • rb_str_update(ptr->string, lpos, ptr->pos ? 1 : 0, c);
  • ptr->pos = clen;
    }
  • clen = p - RSTRING_PTR(ptr->string);

  • rb_str_update(ptr->string, lpos, ptr->pos ? 1 : 0, c);

  • ptr->pos = clen;

    return Qnil;
    }

e$B%A%1%C%He(B #2696 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Assignede$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

This issue was solved with changeset r26588.
Yusuke, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


http://redmine.ruby-lang.org/issues/show/2696