nbtfile 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/VERSION +1 -1
  2. data/lib/nbtfile.rb +42 -5
  3. data/spec/nbtfile_spec.rb +22 -0
  4. metadata +2 -2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
data/lib/nbtfile.rb CHANGED
@@ -34,13 +34,42 @@ class String
34
34
  begin
35
35
  alias_method :_nbtfile_force_encoding, :force_encoding
36
36
  rescue NameError
37
- def _nbtfile_force_encoding(encoding)
37
+ def _nbtfile_force_encoding(encoding) ; end
38
+ end
39
+
40
+ begin
41
+ alias_method :_nbtfile_encode, :encode
42
+ rescue NameError
43
+ def _nbtfile_encode(encoding) ; dup ; end
44
+ end
45
+
46
+ begin
47
+ alias_method :_nbtfile_bytesize, :bytesize
48
+ rescue NameError
49
+ alias_method :_nbtfile_bytesize, :size
50
+ end
51
+
52
+ begin
53
+ alias_method :_nbtfile_valid_encoding?, :valid_encoding?
54
+ rescue NameError
55
+ require 'iconv'
56
+
57
+ def _nbtfile_valid_encoding?
58
+ begin
59
+ Iconv.conv("UTF-8", "UTF-8", self)
60
+ true
61
+ rescue Iconv::IllegalSequence
62
+ false
63
+ end
38
64
  end
39
65
  end
40
66
  end
41
67
 
42
68
  module NBTFile
43
69
 
70
+ class EncodingError < RuntimeError
71
+ end
72
+
44
73
  TOKEN_CLASSES_BY_INDEX = []
45
74
  TOKEN_INDICES_BY_CLASS = {}
46
75
 
@@ -118,7 +147,9 @@ module ReadMethods
118
147
 
119
148
  def read_byte_array(io)
120
149
  length = read_int(io)
121
- read_raw(io, length)
150
+ value = read_raw(io, length)
151
+ value._nbtfile_force_encoding("BINARY")
152
+ value
122
153
  end
123
154
 
124
155
  def read_list_header(io)
@@ -292,12 +323,18 @@ module WriteMethods
292
323
  end
293
324
 
294
325
  def emit_byte_array(io, value)
295
- emit_int(io, value.length)
326
+ value = value.dup
327
+ value._nbtfile_force_encoding("BINARY")
328
+ emit_int(io, value._nbtfile_bytesize)
296
329
  io.write(value)
297
330
  end
298
331
 
299
332
  def emit_string(io, value)
300
- emit_short(io, value.length)
333
+ value = value._nbtfile_encode("UTF-8")
334
+ unless value._nbtfile_valid_encoding?
335
+ raise EncodingError, "Invalid character sequence"
336
+ end
337
+ emit_short(io, value._nbtfile_bytesize)
301
338
  io.write(value)
302
339
  end
303
340
 
@@ -436,7 +473,7 @@ class EndWriterState
436
473
  end
437
474
 
438
475
  class Writer
439
- include WriteMethods
476
+ include Tokens
440
477
 
441
478
  def initialize(stream)
442
479
  @gz = Zlib::GzipWriter.new(stream)
data/spec/nbtfile_spec.rb CHANGED
@@ -196,6 +196,28 @@ describe "NBTFile::emit" do
196
196
  end
197
197
  end
198
198
 
199
+ it "should convert strings to UTF-8 (on encoding-aware rubies)" do
200
+ check_reader_or_writer "\x0a\x00\x03foo" \
201
+ "\x08\x00\x03bar\x00\x04hoge" \
202
+ "\x00",
203
+ [Tokens::TAG_Compound["foo", nil],
204
+ Tokens::TAG_String["bar", "hoge"._nbtfile_encode("UTF-16LE")],
205
+ Tokens::TAG_End["", nil]]
206
+ end
207
+
208
+ it "should reject malformed UTF-8 strings" do
209
+ io = StringIO.new
210
+ NBTFile.emit(io) do |writer|
211
+ writer.emit_compound("foo") do
212
+ lambda {
213
+ str = "hoge\xff"
214
+ str._nbtfile_force_encoding("UTF-8")
215
+ writer.emit_token(Tokens::TAG_String["bar", str])
216
+ }.should raise_error(NBTFile::EncodingError)
217
+ end
218
+ end
219
+ end
220
+
199
221
  emit_shorthand "should support shorthand for emitting lists",
200
222
  "\x0a\x00\x04test" \
201
223
  "\x09\x00\x03foo\x01\x00\x00\x00\x02" \
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 4
9
- version: 0.0.4
8
+ - 5
9
+ version: 0.0.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - MenTaLguY