I found a condition in ID3v2Tag method getbytes where an
ArrayOutOfBoundsException occurs. Now I might be doing
something wrong here :)
Attached is a testcase in jar format. Rename an mp3
file to test.mp3 and run the program twice
Scenario:
Open an mp3 using MP3File remove all the tags and write
new tags. Like
this:
public void save() throws IOException,
NoMPEGFramesException,
ID3v2FormatException,
CorruptHeaderException{
MP3File f = new MP3File (filename,
MP3File.BOTH_TAGS);
f.removeTags(MP3File.EXISTING_TAGS_ONLY);
f.setAlbum (Album);
f.setArtist(Artist);
f.setTitle (Song);
f.writeTags();
}
The class where this is in does NOT go out of scope and
gets called a
second time. The application will crash with the
exception. I added some
debug code around the problem:
if (padding > 0) {
System.err.println ("padding: " + padding+" b: "
+ b.length+" bytesCopied: " + bytesCopied);
System.arraycopy(new byte[padding], 0, b,
bytesCopied, padding);
bytesCopied += padding;
}
This will show:
padding: 16 b: 67 bytesCopied: 67
Apparently it tries to add 16 bytes beyond the allotted
length of the b
[].
testcase
Logged In: YES
user_id=571171
Ok i verified the Bug but i have not the time to solve it
right away.
Take look at the newest CVS. To reproduce run the JUnit
test for this Bug.
Logged In: YES
user_id=215617
After reading the ID3 specs and re-reading the source code,
I think I have determined at least what the problem is.
Somewhere the padding calculation goes bonkers.
I made 3 very simple classes Read, Set and Remove. in
MP3File I added a debug statement that will print the
toString from ID3v2Tag
Read will only open the test.mp3. this will cause the the
info to be printed.
Set will set a tag containing of artist, title and album.
Album will be supplied on the command line.
Remove will only open the file and remove the existing tags.
I started with a mp3 file without tags:
java Read:
--
ID3v2.3.0
TagSize: 0 bytes
Unsynchronisation: false
Extended Header: false
Experimental: false
Footer: false
Padding: 0 bytes
TotalSize: 10 bytes
--
note that the totalsize comes NOT from the file but from the
internal representation of the tag. also note that padding is 0
Now write a tag (java Set 1, this will set the album to "1)
and read it with Read again:
--
ID3v2.3.0
TagSize: 54 bytes
Unsynchronisation: false
Extended Header: false
Experimental: false
Footer: false
Padding: 0 bytes
TotalSize: 64 bytes
TALB
TagAlterDiscard: false
FileAlterDiscard: false
ReadOnly: false
Grouped: false
Compressed: false
Encrypted: false
Unsynchronised: false
LengthIndicator: false
Data: 1
TIT2
TagAlterDiscard: false
FileAlterDiscard: false
ReadOnly: false
Grouped: false
Compressed: false
Encrypted: false
Unsynchronised: false
LengthIndicator: false
Data: The Letter
TPE1
TagAlterDiscard: false
FileAlterDiscard: false
ReadOnly: false
Grouped: false
Compressed: false
Encrypted: false
Unsynchronised: false
LengthIndicator: false
Data: Joe Cocker
--
Note that the total size 64 is the 54 bytes data plus the
header this is correct.
Now set another album using the Set class (java Set 2
meaning set the album to "2")
The program does not crash BUT look at the padding:
--
ID3v2.3.0
TagSize: 54 bytes
Unsynchronisation: false
Extended Header: false
Experimental: false
Footer: false
Padding: 353 bytes
TotalSize: 64 bytes
<rest of the output removed. TALB was set to 2>
Where does the 353 come from?
Running the Set program a third time will give the crash:
--
padding: 353 b: 64 bytesCopied: 64
java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at helliker.id3.ID3v2Tag.getBytes(ID3v2Tag.java:374)
at helliker.id3.ID3v2Tag.writeTag(ID3v2Tag.java:265)
at helliker.id3.MP3File.writeTags(MP3File.java:478)
at Set.save(Set.java:16)
at Set.main(Set.java:28)
--
Continueing the search :)
Logged In: YES
user_id=730046
I've recently had a similar problem. IMHO
padding = getUpdatedPadding();
has to be called *before* getTotalSize() because
getTotalSize() internally uses the padding property.
You can achieve this by moving the above statement to the
beginning of
getBytes() as I've done here:
http://tinyurl.com/2dxa6
My latest revision, where I've indepently fixed bug 916695,
too can be found at
http://cvs.sourceforge.net/viewcvs.py/mp3dings/helliker.id3/ID3v2Tag.java?view=markup
I hope this solves your problem (I haven't checked).
Logged In: YES
user_id=730046
Someone else had already solved this: see bug 681321