Skip to content

Commit

Permalink
[GR-17457] Fix StringIO#ungetbyte behaviour and add specs.
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/2913
  • Loading branch information
aardvark179 committed Sep 13, 2021
2 parents ab28c3e + a4b8de3 commit a52bd0f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Bug fixes:
* Fix handling of incompatible types in `Float#<=>` (#2432, @chrisseaton).
* Fix issue with escaping curly braces for `Dir.glob` (#2425).
* Fix `base64` decoding issue with missing output (#2435).
* Fix `StringIO#ungetbyte` to treat a byte as a byte, not a code point (#2436).

Compatibility:

Expand Down
10 changes: 5 additions & 5 deletions lib/truffle/stringio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -599,20 +599,20 @@ def ungetbyte(bytes)
return unless bytes

if bytes.kind_of? Integer
bytes = '' << bytes
bytes = ''.b << (bytes & 0xff)
else
bytes = StringValue(bytes)
bytes = StringValue(bytes).b
return if bytes.bytesize == 0
end

d = @__data__
pos = d.pos
string = d.string
string = d.string.b

enc = string.encoding
enc = d.string.encoding

if d.pos == 0
d.string = "#{bytes}#{string}"
d.string = bytes << string
else
size = bytes.bytesize
a = string.byteslice(0, pos - size) if size < pos
Expand Down
38 changes: 37 additions & 1 deletion spec/ruby/library/stringio/ungetbyte_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
# frozen_string_literal: false
require_relative '../../spec_helper'
require 'stringio'

describe "StringIO#ungetbyte" do
it "needs to be reviewed for spec completeness"
it "ungets a single byte from a string starting with a single byte character" do
str = 'This is a simple string.'
io = StringIO.new("#{str}")
c = io.getc
c.should == 'T'
io.ungetbyte(83)
io.string.should == 'Shis is a simple string.'
end

it "ungets a single byte from a string in the middle of a multibyte characte" do
str = "\u01a9"
io = StringIO.new(str)
b = io.getbyte
b.should == 0xc6 # First byte of UTF-8 encoding of \u01a9
io.ungetbyte(0xce) # First byte of UTF-8 encoding of \u03a9
io.string.should == "\u03a9"
end

it "constrains the value of a numeric argument to a single byte" do
str = 'This is a simple string.'
io = StringIO.new("#{str}")
c = io.getc
c.should == 'T'
io.ungetbyte(83 | 0xff00)
io.string.should == 'Shis is a simple string.'
end

it "ungets the bytes of a string if given a string as an arugment" do
str = "\u01a9"
io = StringIO.new(str)
b = io.getbyte
b.should == 0xc6 # First byte of UTF-8 encoding of \u01a9
io.ungetbyte("\u01a9")
io.string.bytes.should == [198, 169, 169]
end

end

0 comments on commit a52bd0f

Please sign in to comment.