| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 // Number of bits in .ICO/.CUR used to store the directory and its entries, | 41 // Number of bits in .ICO/.CUR used to store the directory and its entries, |
| 42 // respectively (doesn't match sizeof values for member structs since we omit | 42 // respectively (doesn't match sizeof values for member structs since we omit |
| 43 // some fields). | 43 // some fields). |
| 44 static const size_t sizeOfDirectory = 6; | 44 static const size_t sizeOfDirectory = 6; |
| 45 static const size_t sizeOfDirEntry = 16; | 45 static const size_t sizeOfDirEntry = 16; |
| 46 | 46 |
| 47 ICOImageDecoder::ICOImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOp
tion colorOptions, size_t maxDecodedBytes) | 47 ICOImageDecoder::ICOImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOp
tion colorOptions, size_t maxDecodedBytes) |
| 48 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes) | 48 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes) |
| 49 , m_fastReader(nullptr) | 49 , m_fastReader(nullptr) |
| 50 , m_decodedOffset(0) | 50 , m_decodedOffset(0) |
| 51 , m_dirEntriesCount(0) |
| 51 { | 52 { |
| 52 } | 53 } |
| 53 | 54 |
| 54 ICOImageDecoder::~ICOImageDecoder() | 55 ICOImageDecoder::~ICOImageDecoder() |
| 55 { | 56 { |
| 56 } | 57 } |
| 57 | 58 |
| 58 void ICOImageDecoder::onSetData(SegmentReader* data) | 59 void ICOImageDecoder::onSetData(SegmentReader* data) |
| 59 { | 60 { |
| 60 m_fastReader.setData(data); | 61 m_fastReader.setData(data); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 176 } |
| 176 } | 177 } |
| 177 | 178 |
| 178 bool ICOImageDecoder::decodeDirectory() | 179 bool ICOImageDecoder::decodeDirectory() |
| 179 { | 180 { |
| 180 // Read and process directory. | 181 // Read and process directory. |
| 181 if ((m_decodedOffset < sizeOfDirectory) && !processDirectory()) | 182 if ((m_decodedOffset < sizeOfDirectory) && !processDirectory()) |
| 182 return false; | 183 return false; |
| 183 | 184 |
| 184 // Read and process directory entries. | 185 // Read and process directory entries. |
| 185 return (m_decodedOffset >= (sizeOfDirectory + (m_dirEntries.size() * sizeOfD
irEntry))) || processDirectoryEntries(); | 186 return (m_decodedOffset >= (sizeOfDirectory + (m_dirEntriesCount * sizeOfDir
Entry))) || processDirectoryEntries(); |
| 186 } | 187 } |
| 187 | 188 |
| 188 bool ICOImageDecoder::decodeAtIndex(size_t index) | 189 bool ICOImageDecoder::decodeAtIndex(size_t index) |
| 189 { | 190 { |
| 190 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); | 191 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); |
| 191 const IconDirectoryEntry& dirEntry = m_dirEntries[index]; | 192 const IconDirectoryEntry& dirEntry = m_dirEntries[index]; |
| 192 const ImageType imageType = imageTypeAtIndex(index); | 193 const ImageType imageType = imageTypeAtIndex(index); |
| 193 if (imageType == Unknown) | 194 if (imageType == Unknown) |
| 194 return false; // Not enough data to determine image type yet. | 195 return false; // Not enough data to determine image type yet. |
| 195 | 196 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 222 return !m_pngDecoders[index]->failed() || setFailed(); | 223 return !m_pngDecoders[index]->failed() || setFailed(); |
| 223 } | 224 } |
| 224 | 225 |
| 225 bool ICOImageDecoder::processDirectory() | 226 bool ICOImageDecoder::processDirectory() |
| 226 { | 227 { |
| 227 // Read directory. | 228 // Read directory. |
| 228 ASSERT(!m_decodedOffset); | 229 ASSERT(!m_decodedOffset); |
| 229 if (m_data->size() < sizeOfDirectory) | 230 if (m_data->size() < sizeOfDirectory) |
| 230 return false; | 231 return false; |
| 231 const uint16_t fileType = readUint16(2); | 232 const uint16_t fileType = readUint16(2); |
| 232 const uint16_t idCount = readUint16(4); | 233 m_dirEntriesCount = readUint16(4); |
| 233 m_decodedOffset = sizeOfDirectory; | 234 m_decodedOffset = sizeOfDirectory; |
| 234 | 235 |
| 235 // See if this is an icon filetype we understand, and make sure we have at | 236 // See if this is an icon filetype we understand, and make sure we have at |
| 236 // least one entry in the directory. | 237 // least one entry in the directory. |
| 237 if (((fileType != ICON) && (fileType != CURSOR)) || (!idCount)) | 238 if (((fileType != ICON) && (fileType != CURSOR)) || (!m_dirEntriesCount)) |
| 238 return setFailed(); | 239 return setFailed(); |
| 239 | 240 |
| 240 m_fileType = static_cast<FileType>(fileType); | 241 m_fileType = static_cast<FileType>(fileType); |
| 241 | |
| 242 // Enlarge member vectors to hold all the entries. | |
| 243 m_dirEntries.resize(idCount); | |
| 244 m_bmpReaders.resize(idCount); | |
| 245 m_pngDecoders.resize(idCount); | |
| 246 return true; | 242 return true; |
| 247 } | 243 } |
| 248 | 244 |
| 249 bool ICOImageDecoder::processDirectoryEntries() | 245 bool ICOImageDecoder::processDirectoryEntries() |
| 250 { | 246 { |
| 251 // Read directory entries. | 247 // Read directory entries. |
| 252 ASSERT(m_decodedOffset == sizeOfDirectory); | 248 ASSERT(m_decodedOffset == sizeOfDirectory); |
| 253 if ((m_decodedOffset > m_data->size()) || ((m_data->size() - m_decodedOffset
) < (m_dirEntries.size() * sizeOfDirEntry))) | 249 if ((m_decodedOffset > m_data->size()) || ((m_data->size() - m_decodedOffset
) < (m_dirEntriesCount * sizeOfDirEntry))) |
| 254 return false; | 250 return false; |
| 251 |
| 252 // Enlarge member vectors to hold all the entries. |
| 253 m_dirEntries.resize(m_dirEntriesCount); |
| 254 m_bmpReaders.resize(m_dirEntriesCount); |
| 255 m_pngDecoders.resize(m_dirEntriesCount); |
| 256 |
| 255 for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); i != m_dirEntri
es.end(); ++i) | 257 for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); i != m_dirEntri
es.end(); ++i) |
| 256 *i = readDirectoryEntry(); // Updates m_decodedOffset. | 258 *i = readDirectoryEntry(); // Updates m_decodedOffset. |
| 257 | 259 |
| 258 // Make sure the specified image offsets are past the end of the directory | 260 // Make sure the specified image offsets are past the end of the directory |
| 259 // entries. | 261 // entries. |
| 260 for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); i != m_dirEntri
es.end(); ++i) { | 262 for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); i != m_dirEntri
es.end(); ++i) { |
| 261 if (i->m_imageOffset < m_decodedOffset) | 263 if (i->m_imageOffset < m_decodedOffset) |
| 262 return setFailed(); | 264 return setFailed(); |
| 263 } | 265 } |
| 264 | 266 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); | 327 ASSERT_WITH_SECURITY_IMPLICATION(index < m_dirEntries.size()); |
| 326 const uint32_t imageOffset = m_dirEntries[index].m_imageOffset; | 328 const uint32_t imageOffset = m_dirEntries[index].m_imageOffset; |
| 327 if ((imageOffset > m_data->size()) || ((m_data->size() - imageOffset) < 4)) | 329 if ((imageOffset > m_data->size()) || ((m_data->size() - imageOffset) < 4)) |
| 328 return Unknown; | 330 return Unknown; |
| 329 char buffer[4]; | 331 char buffer[4]; |
| 330 const char* data = m_fastReader.getConsecutiveData(imageOffset, 4, buffer); | 332 const char* data = m_fastReader.getConsecutiveData(imageOffset, 4, buffer); |
| 331 return strncmp(data, "\x89PNG", 4) ? BMP : PNG; | 333 return strncmp(data, "\x89PNG", 4) ? BMP : PNG; |
| 332 } | 334 } |
| 333 | 335 |
| 334 } // namespace blink | 336 } // namespace blink |
| OLD | NEW |