nbtfile 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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