Commit message: Reverse the version check, similarly to what mp4v2 does
CVE: CVE-2012-2396
CWE: NVD-CWE-Other
Vulnerability description: VideoLAN VLC media player 2.0.1 allows remote attackers to cause a denial of service (divide-by-zero error and application crash) via a crafted MP4 file.

Project: taglib
File: mp4properties.cpp

MP4::Properties::~Properties()
{
  delete d;
}

Project: taglib
File: mp4properties.cpp

MP4::Properties::sampleRate() const
{
  return d->sampleRate;
}

Project: taglib
File: mp4properties.cpp

MP4::Properties::bitrate() const
{
  return d->bitrate;
}

Project: taglib
File: mp4properties.cpp

  PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0) {}

Project: taglib
File: mp4properties.cpp

MP4::Properties::channels() const
{
  return d->channels;
}

Project: taglib
File: mp4properties.cpp

MP4::Properties::length() const
{
  return d->length;
}

Project: taglib
File: mp4properties.cpp

MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
  : AudioProperties(style)
{
  d = new PropertiesPrivate;

  MP4::Atom *moov = atoms->find("moov");
  if(!moov) {
    debug("MP4: Atom 'moov' not found");
    return;
  }

  MP4::Atom *trak = 0;
  ByteVector data;

  MP4::AtomList trakList = moov->findall("trak");
  for (unsigned int i = 0; i < trakList.size(); i++) {
    trak = trakList[i];
    MP4::Atom *hdlr = trak->find("mdia", "hdlr");
    if(!hdlr) {
      debug("MP4: Atom 'trak.mdia.hdlr' not found");
      return;
    }
    file->seek(hdlr->offset);
    data = file->readBlock(hdlr->length);
    if(data.mid(16, 4) == "soun") {
      break;
    }
    trak = 0;
  }
  if (!trak) {
    debug("MP4: No audio tracks");
    return;
  }

  MP4::Atom *mdhd = trak->find("mdia", "mdhd");
  if(!mdhd) {
    debug("MP4: Atom 'trak.mdia.mdhd' not found");
    return;
  }

  file->seek(mdhd->offset);
  data = file->readBlock(mdhd->length);
  uint version = data[8];
  if(version == 1) {
    if (data.size() < 36 + 8) {
      debug("MP4: Atom 'trak.mdia.mdhd' is smaller than expected");
      return;
    }
    long long unit = data.mid(28, 8).toLongLong();
    long long length = data.mid(36, 8).toLongLong();
    d->length = unit ? int(length / unit) : 0;
  }
  else {
    if (data.size() < 24 + 4) {
      debug("MP4: Atom 'trak.mdia.mdhd' is smaller than expected");
      return;
    }
    unsigned int unit = data.mid(20, 4).toUInt();
    unsigned int length = data.mid(24, 4).toUInt();
    d->length = unit ? length / unit : 0;
  }

  MP4::Atom *atom = trak->find("mdia", "minf", "stbl", "stsd");
  if(!atom) {
    return;
  }

  file->seek(atom->offset);
  data = file->readBlock(atom->length);
  if(data.mid(20, 4) == "mp4a") {
    d->channels = data.mid(40, 2).toShort();
    d->bitsPerSample = data.mid(42, 2).toShort();
    d->sampleRate = data.mid(46, 4).toUInt();
    if(data.mid(56, 4) == "esds" && data[64] == 0x03) {
      long pos = 65;
      if(data.mid(pos, 3) == "\x80\x80\x80") {
        pos += 3;
      }
      pos += 4;
      if(data[pos] == 0x04) {
        pos += 1;
        if(data.mid(pos, 3) == "\x80\x80\x80") {
          pos += 3;
        }
        pos += 10;
        d->bitrate = (data.mid(pos, 4).toUInt() + 500) / 1000;
      }
    }
  }
}

Project: taglib
File: mp4properties.cpp

MP4::Properties::bitsPerSample() const
{
  return d->bitsPerSample;
}