apetag 1.1.1 → 1.1.2

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 (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: