diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/stringio/stringio.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index 86ff56534c..b7c67f2aad 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -771,15 +771,24 @@ strio_ungetc(self, ch) int cc = NUM2INT(ch); long len, pos = ptr->pos; - if (cc != EOF && pos > 0) { - if ((len = RSTRING(ptr->string)->len) < pos-- || - (unsigned char)RSTRING(ptr->string)->ptr[pos] != - (unsigned char)cc) { - strio_extend(ptr, pos, 1); - RSTRING(ptr->string)->ptr[pos] = cc; - OBJ_INFECT(ptr->string, self); + if (cc != EOF) { + len = RSTRING(ptr->string)->len; + if (pos == 0) { + char *p; + rb_str_resize(ptr->string, len + 1); + p = RSTRING(ptr->string)->ptr; + memmove(p + 1, p, len); + } + else { + if (len < pos-- || + (unsigned char)RSTRING(ptr->string)->ptr[pos] != + (unsigned char)cc) { + strio_extend(ptr, pos, 1); + } + --ptr->pos; } - --ptr->pos; + RSTRING(ptr->string)->ptr[pos] = cc; + OBJ_INFECT(ptr->string, self); ptr->flags &= ~STRIO_EOF; } return Qnil; |