Code: void SparseBitSet::initFromRanges(const uint32_t* ranges, size_t nRanges) {
 if (nRanges == 0) {
        mMaxVal = 0;
        mIndices.reset();
        mBitmaps.reset();
 return;
 }
    mMaxVal = ranges[nRanges * 2 - 1];
 size_t indexSize = (mMaxVal + kPageMask) >> kLogValuesPerPage;
    mIndices.reset(new uint32_t[indexSize]);
 uint32_t nPages = calcNumPages(ranges, nRanges);
    mBitmaps.reset(new element[nPages << (kLogValuesPerPage - kLogBitsPerEl)]);
    memset(mBitmaps.get(), 0, nPages << (kLogValuesPerPage - 3));
    mZeroPageIndex = noZeroPage;
 uint32_t nonzeroPageEnd = 0;
 uint32_t currentPage = 0;

     for (size_t i = 0; i < nRanges; i++) {
         uint32_t start = ranges[i * 2];
         uint32_t end = ranges[i * 2 + 1];
         uint32_t startPage = start >> kLogValuesPerPage;
         uint32_t endPage = (end - 1) >> kLogValuesPerPage;
         if (startPage >= nonzeroPageEnd) {
 if (startPage > nonzeroPageEnd) {
 if (mZeroPageIndex == noZeroPage) {
                    mZeroPageIndex = (currentPage++) << (kLogValuesPerPage - kLogBitsPerEl);
 }
 for (uint32_t j = nonzeroPageEnd; j < startPage; j++) {
                    mIndices[j] = mZeroPageIndex;
 }
 }
            mIndices[startPage] = (currentPage++) << (kLogValuesPerPage - kLogBitsPerEl);
 }

 size_t index = ((currentPage - 1) << (kLogValuesPerPage - kLogBitsPerEl)) +
 ((start & kPageMask) >> kLogBitsPerEl);
 size_t nElements = (end - (start & ~kElMask) + kElMask) >> kLogBitsPerEl;
 if (nElements == 1) {
            mBitmaps[index] |= (kElAllOnes >> (start & kElMask)) &
 (kElAllOnes << ((-end) & kElMask));
 } else {
            mBitmaps[index] |= kElAllOnes >> (start & kElMask);
 for (size_t j = 1; j < nElements - 1; j++) {
                mBitmaps[index + j] = kElAllOnes;
 }
            mBitmaps[index + nElements - 1] |= kElAllOnes << ((-end) & kElMask);
 }
 for (size_t j = startPage + 1; j < endPage + 1; j++) {
            mIndices[j] = (currentPage++) << (kLogValuesPerPage - kLogBitsPerEl);
 }
        nonzeroPageEnd = endPage + 1;
 }
}

Vulnerability Type: DoS Mem. Corr. 
CWE ID: CWE-20
Summary: The Minikin library in Android 5.0.x before 5.0.2, 5.1.x before 5.1.1, and 6.x before 2016-04-01 does not properly consider negative size values in font data, which allows remote attackers to cause a denial of service (memory corruption and reboot loop) via a crafted font, aka internal bug 26413177.
Commit Message: Reject fonts with invalid ranges in cmap

A corrupt or malicious font may have a negative size in its cmap
range, which in turn could lead to memory corruption. This patch
detects the case and rejects the font, and also includes an assertion
in the sparse bit set implementation if we missed any such case.

External issue:
https://code.google.com/p/android/issues/detail?id=192618

Bug: 26413177
Change-Id: Icc0c80e4ef389abba0964495b89aa0fae3e9f4b2
