apetag 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/apetag.rb +11 -12
  2. data/test/test_apetag.rb +23 -6
  3. metadata +5 -5
data/apetag.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # This library implements a APEv2 parser/generator.
2
+ # This library implements a APEv2 reader/writer.
3
3
  # If called from the command line, it prints out the contents of the APEv2 tag
4
4
  # for the given filename arguments.
5
5
  #
@@ -61,7 +61,6 @@
61
61
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
62
62
  # SOFTWARE.
63
63
 
64
- require 'set'
65
64
  require 'cicphash'
66
65
 
67
66
  # Error raised by the library
@@ -189,8 +188,8 @@ end
189
188
  class ApeTag
190
189
  MAX_SIZE = 8192
191
190
  MAX_ITEM_COUNT = 64
192
- HEADER_FLAGS = "\x00\x00\x00\xA0"
193
- FOOTER_FLAGS = "\x00\x00\x00\x80"
191
+ HEADER_FLAGS = "\x00\x00\xA0"
192
+ FOOTER_FLAGS = "\x00\x00\x80"
194
193
  PREAMBLE = "APETAGEX\xD0\x07\x00\x00"
195
194
  RECOMMENDED_KEYS = %w'Title Artist Album Year Comment Genre Track Subtitle
196
195
  Publisher Conductor Composer Copyright Publicationright File EAN/UPC ISBN
@@ -249,8 +248,7 @@ class ApeTag
249
248
  @check_id3 = check_id3.nil? ? @@check_id3 : check_id3
250
249
  else
251
250
  @filename = filename.to_s
252
- @check_id3 = check_id3 unless check_id3.nil?
253
- @check_id3 = !MP3_RE.match(@filename).nil? if @check_id3.nil?
251
+ @check_id3 = check_id3.nil? ? !MP3_RE.match(@filename).nil? : check_id3
254
252
  end
255
253
  end
256
254
 
@@ -368,11 +366,12 @@ class ApeTag
368
366
  end
369
367
  file.seek(-32-id3.length, IO::SEEK_END)
370
368
  tag_footer = file.read(32)
371
- unless tag_footer[0...12] == PREAMBLE && tag_footer[20...24] == FOOTER_FLAGS
369
+ unless tag_footer[0...12] == PREAMBLE
372
370
  @has_tag = false
373
371
  @tag_start = file_size - id3.length
374
372
  return
375
373
  end
374
+ raise ApeTagError, "Tag has bad footer flags" unless tag_footer[21...24] == FOOTER_FLAGS && (tag_footer[20...21] == "\x00" || tag_footer[20...21] == "\x01")
376
375
  @tag_footer = tag_footer
377
376
  @tag_size, @tag_item_count = tag_footer[12...20].unpack('VV')
378
377
  @tag_size += 32
@@ -385,9 +384,9 @@ class ApeTag
385
384
  @tag_start=file.pos
386
385
  @tag_header=file.read(32)
387
386
  @tag_data=file.read(tag_size-64)
388
- raise ApeTagError, "Missing header" unless tag_header[0...12] == PREAMBLE && tag_header[20...24] == HEADER_FLAGS
389
- raise ApeTagError, "Header and footer size does match" unless tag_size == tag_header[12...16].unpack('V')[0] + 32
390
- raise ApeTagError, "Header and footer item count does match" unless tag_item_count == tag_header[16...20].unpack('V')[0]
387
+ raise ApeTagError, "Missing header" unless tag_header[0...12] == PREAMBLE && tag_header[21...24] == HEADER_FLAGS && (tag_header[20...21] == "\x00" || tag_header[20...21] == "\x01")
388
+ raise ApeTagError, "Header and footer size does not match" unless tag_size == tag_header[12...16].unpack('V')[0] + 32
389
+ raise ApeTagError, "Header and footer item count does not match" unless tag_item_count == tag_header[16...20].unpack('V')[0]
391
390
  @has_tag = true
392
391
  end
393
392
 
@@ -428,8 +427,8 @@ class ApeTag
428
427
  @tag_size = tag_data.length + 64
429
428
  base_start = "#{PREAMBLE}#{[tag_size-32, tag_item_count].pack('VV')}"
430
429
  base_end = "\0"*8
431
- @tag_header = "#{base_start}#{HEADER_FLAGS}#{base_end}"
432
- @tag_footer = "#{base_start}#{FOOTER_FLAGS}#{base_end}"
430
+ @tag_header = "#{base_start}\x00#{HEADER_FLAGS}#{base_end}"
431
+ @tag_footer = "#{base_start}\x00#{FOOTER_FLAGS}#{base_end}"
433
432
  raise ApeTagError, "Updated tag has too many items (#{tag_item_count})" if tag_item_count > MAX_ITEM_COUNT
434
433
  raise ApeTagError, "Updated tag too large (#{tag_size})" if tag_size > MAX_SIZE
435
434
  end
@@ -228,7 +228,7 @@ class ApeTagTest < Test::Unit::TestCase
228
228
  assert_equal "XYZ", ai.string_value
229
229
 
230
230
  # Test parsing of invalid UTF-8
231
- data = "\012\0\0\0\07\0\0\0BlaH\0BlAh\0XYZ\0\xff"
231
+ data = "\012\0\0\0\0\0\0\0BlaH\0BlAh\0XYZ\0\xff"
232
232
  assert_raises(ApeTagError){ApeItem.parse(data, 0)}
233
233
  end
234
234
 
@@ -237,6 +237,23 @@ class ApeTagTest < Test::Unit::TestCase
237
237
  data = EMPTY_APE_TAG.dup
238
238
  # Test default case OK
239
239
  assert_nothing_raised{ApeTag.new(StringIO.new(data)).raw}
240
+
241
+ # Test read only tags work
242
+ data[20] = 1
243
+ assert_nothing_raised{ApeTag.new(StringIO.new(data)).raw}
244
+
245
+ # Test other flags values don't work
246
+ 2.upto(255) do |i|
247
+ data[20] = i
248
+ assert_raises(ApeTagError){ApeTag.new(StringIO.new(data)).raw}
249
+ end
250
+ data[20] = 1
251
+ 2.upto(255) do |i|
252
+ data[52] = i
253
+ assert_raises(ApeTagError){ApeTag.new(StringIO.new(data)).raw}
254
+ data[20] = i
255
+ assert_raises(ApeTagError){ApeTag.new(StringIO.new(data)).raw}
256
+ end
240
257
 
241
258
  # Test footer size less than minimum size (32)
242
259
  data[44] = 31
@@ -284,7 +301,7 @@ class ApeTagTest < Test::Unit::TestCase
284
301
 
285
302
  # Test unmatched header and footer item count, footer size wrong
286
303
  data = EXAMPLE_APE_TAG.dup
287
- data[48] -=1
304
+ data[208-16] -=1
288
305
  assert_raises(ApeTagError){ApeTag.new(StringIO.new(data)).fields}
289
306
 
290
307
  # Test missing/corrupt header
@@ -330,7 +347,7 @@ class ApeTagTest < Test::Unit::TestCase
330
347
  data[192] += 2
331
348
  assert_raises(ApeTagError){ApeTag.new(StringIO.new(data)).fields}
332
349
 
333
- # Test updating works in case insensitive manner
350
+ # Test updating works in a case insensitive manner
334
351
  assert_equal ['blah'], ApeTag.new(StringIO.new(EXAMPLE_APE_TAG.dup)).update{|x| x['album']='blah'}['ALBUM']
335
352
  assert_equal ['blah'], ApeTag.new(StringIO.new(EXAMPLE_APE_TAG.dup)).update{|x| x['ALBUM']='blah'}['album']
336
353
  assert_equal ['blah'], ApeTag.new(StringIO.new(EXAMPLE_APE_TAG.dup)).update{|x| x['ALbUM']='blah'}['albuM']
@@ -345,10 +362,10 @@ class ApeTagTest < Test::Unit::TestCase
345
362
  # Test ID3v1.0 tag
346
363
  assert_nothing_raised{ApeTag.new(StringIO.new(EXAMPLE_APE_TAG[0...-128] + EXAMPLE_APE_TAG[-128..-1].gsub("\0", " "))).update{|x| x}}
347
364
 
348
- # Test updating with invalid value
365
+ # Test updating with an invalid value
349
366
  assert_raises(ApeTagError){ApeTag.new(StringIO.new(EMPTY_APE_TAG.dup)).update{|x| x['Album']="\xfe"}}
350
367
 
351
- # Test updating with invalid key
368
+ # Test updating with an invalid key
352
369
  assert_raises(ApeTagError){ApeTag.new(StringIO.new(EMPTY_APE_TAG.dup)).update{|x| x['x']=""}}
353
370
 
354
371
  # Test updating with too many items
@@ -358,7 +375,7 @@ class ApeTagTest < Test::Unit::TestCase
358
375
 
359
376
  # Test updating with too large a tag
360
377
  assert_raises(ApeTagError){ApeTag.new(StringIO.new(EMPTY_APE_TAG.dup)).update{|x| x['xx']=' '*8118}}
361
- # Test updating with just enough tag
378
+ # Test updating with a just large enough tag
362
379
  assert_nothing_raised{ApeTag.new(StringIO.new(EMPTY_APE_TAG.dup)).update{|x| x['xx']=' '*8117}}
363
380
  end
364
381
 
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: apetag
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.1.1
7
- date: 2007-08-20 00:00:00 -07:00
8
- summary: APEv2 Tag Parser/Generator
6
+ version: 1.1.2
7
+ date: 2007-11-07 00:00:00 -08:00
8
+ summary: APEv2 Tag Reader/Writer
9
9
  require_paths:
10
10
  - .
11
11
  email: code@jeremyevans.net
12
12
  homepage:
13
- rubyforge_project:
13
+ rubyforge_project: apetag
14
14
  description:
15
15
  autorequire: apetag
16
16
  default_executable: