Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Parsing ordered Codecbooks :-( (Read 2173 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Parsing ordered Codecbooks :-(

EDIT link to sample file

After someone notified me that AVI-Mux GUI does not read some vorbis files, I found that my parser does not handle ordered codebooks properly (I need to parse the entire header, since the information I need, the window sizes, are the very last elements), while unordered codebooks work properly.

Since the file can be played, and a file with broken codebooks would hardly be playable, I conclude that the file is valid.

Page numbers refer to the Vorbis_I_spec.pdf file now.

When trying to parse an ordered codebook, the result is that I don't have a syncword at the position where the next codebook should start. Even item 7 on page 14 { 7) if [current_entry] is greater than [codebook_entries] ERROR CONDITION;
the decoder will not be able to read this stream.
} does not work out. Even worse, I compared my code to the corresponding section in libvorbis, and I don't see any difference.

Note that I don't need the codebooks themselves, but that I just need to parse throw them to finally get the window sizes.

Here is the code which obviously does not work out:

   int i;
   packet->GetPos();
   int sync_word = packet->ReadBits(24,1);
   int codebook_dim = packet->ReadBits(16,1);
   int codebook_entries = packet->ReadBits(24,1);
   int ordered = packet->ReadBits(1,1);
   int length = 0;
   int* lengths = new int[codebook_entries];

   if (!ordered) {
      int sparse = packet->ReadBits(1,1);
      for (i=0;i<codebook_entries;i++) {
         if (sparse) {
            if (packet->ReadBits(1,1)) {
               // entry used
               length = packet->ReadBits(5,1)+1;
            }
         } else {
            length = packet->ReadBits(5,1)+1;
         }
         lengths = length;
      }
   } else {
      int current_entry = 0;
      int current_length = 1+packet->ReadBits(5,1);
      while (current_entry < codebook_entries) {
         int number = packet->ReadBits(ilog(codebook_entries - current_entry));
         current_entry += number;
         current_length++;
      }

      if (current_entry > codebook_entries) {
         Sleep(1); // B0rked !!  <= debugger breakpoint here
      }
   }

   int codebook_lookup_type = packet->ReadBits(4,1);

Since ordered codebooks work, the problem can only be someone within the indicated section, but I don't see any difference to the code of libvorbis, except that libvorbis does not report an error condition if the described algorithm on page 14 causes a violation of current_entry > codebook_entries (it rather uses an algorithm which is equivalent if the described one does not raise this error condition).

Does anyone see what is wrong in my code? Note: The currently available code on my homepage has an additional error (the line int sparse = packet->ReadBits(1,1); is misplaced, so that can't work).

More tests:
- unordered codebooks are correctly parsed with codebook_lookup_type 0 and 1. I have not yet seen a file with type 2. However, since the first codebook of the test file i got is unordered and uses codebook_lookup_type = 0, and the 2nd (ordered) codebook starts at a correct syncword, but is not parsed correctly, this cannot be the problem causing my code to malfunction.