Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5582823a authored by Ray Essick's avatar Ray Essick Committed by gitbuildkicker
Browse files

better validation lengths of strings in ID3 tags

Validate lengths on strings in ID3 tags, particularly around 0.
Also added code to handle cases when we can't get memory for
copies of strings we want to extract from these tags.

Affects L/M/N/master, same patch for all of them.

Bug: 30744884
Change-Id: I2675a817a39f0927ec1f7e9f9c09f2e61020311e
Test: play mp3 file which caused a <0 length.
parent 435096f7
Loading
Loading
Loading
Loading
+42 −15
Original line number Diff line number Diff line
@@ -77,7 +77,10 @@ ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1)
      mFirstFrameOffset(0),
      mVersion(ID3_UNKNOWN),
      mRawSize(0) {
    sp<MemorySource> source = new MemorySource(data, size);
    sp<MemorySource> source = new (std::nothrow) MemorySource(data, size);

    if (source == NULL)
        return;

    mIsValid = parseV2(source, 0);

@@ -542,6 +545,10 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
        n -= skipped;
    }

    if (n <= 0) {
       return;
    }

    if (encoding == 0x00) {
        // supposedly ISO 8859-1
        id->setTo((const char*)frameData + 1, n);
@@ -555,11 +562,16 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
        const char16_t *framedata = (const char16_t *) (frameData + 1);
        char16_t *framedatacopy = NULL;
#if BYTE_ORDER == LITTLE_ENDIAN
        framedatacopy = new char16_t[len];
        if (len > 0) {
            framedatacopy = new (std::nothrow) char16_t[len];
            if (framedatacopy == NULL) {
                return;
            }
            for (int i = 0; i < len; i++) {
                framedatacopy[i] = bswap_16(framedata[i]);
            }
            framedata = framedatacopy;
        }
#endif
        id->setTo(framedata, len);
        if (framedatacopy != NULL) {
@@ -572,15 +584,26 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
        const char16_t *framedata = (const char16_t *) (frameData + 1);
        char16_t *framedatacopy = NULL;
        if (*framedata == 0xfffe) {
            // endianness marker doesn't match host endianness, convert
            framedatacopy = new char16_t[len];
            // endianness marker != host endianness, convert & skip
            if (len <= 1) {
                return;         // nothing after the marker
            }
            framedatacopy = new (std::nothrow) char16_t[len];
            if (framedatacopy == NULL) {
                return;
            }
            for (int i = 0; i < len; i++) {
                framedatacopy[i] = bswap_16(framedata[i]);
            }
            framedata = framedatacopy;
            // and skip over the marker
            framedata++;
            len--;
        } else if (*framedata == 0xfeff) {
            // endianness marker == host endianness, skip it
            if (len <= 1) {
                return;         // nothing after the marker
            }
        // If the string starts with an endianness marker, skip it
        if (*framedata == 0xfeff) {
            framedata++;
            len--;
        }
@@ -595,7 +618,8 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
        }
        if (eightBit) {
            // collapse to 8 bit, then let the media scanner client figure out the real encoding
            char *frame8 = new char[len];
            char *frame8 = new (std::nothrow) char[len];
            if (frame8 != NULL) {
                for (int i = 0; i < len; i++) {
                    frame8[i] = framedata[i];
                }
@@ -604,6 +628,9 @@ void ID3::Iterator::getstring(String8 *id, bool otherdata) const {
            } else {
                id->setTo(framedata, len);
            }
        } else {
            id->setTo(framedata, len);
        }

        if (framedatacopy != NULL) {
            delete[] framedatacopy;