mirror of
https://github.com/webmproject/libwebp.git
synced 2025-08-29 07:12:05 +02:00
Speed-up chunk list operations.
The chunk list only has two operations: append and set to one element. The two operations are split and the append one is sped up by storing the last element. Corrupted data could make a very long list to search through. BUG=oss-fuzz:9190 Change-Id: I1aa813ca629df29efaa3b46dbd4c4c42dbeaa34c
This commit is contained in:
@@ -111,27 +111,6 @@ WebPChunk* ChunkSearchList(WebPChunk* first, uint32_t nth, uint32_t tag) {
|
||||
return ((nth > 0) && (iter > 0)) ? NULL : first;
|
||||
}
|
||||
|
||||
// Outputs a pointer to 'prev_chunk->next_',
|
||||
// where 'prev_chunk' is the pointer to the chunk at position (nth - 1).
|
||||
// Returns true if nth chunk was found.
|
||||
static int ChunkSearchListToSet(WebPChunk** chunk_list, uint32_t nth,
|
||||
WebPChunk*** const location) {
|
||||
uint32_t count = 0;
|
||||
assert(chunk_list != NULL);
|
||||
*location = chunk_list;
|
||||
|
||||
while (*chunk_list != NULL) {
|
||||
WebPChunk* const cur_chunk = *chunk_list;
|
||||
++count;
|
||||
if (count == nth) return 1; // Found.
|
||||
chunk_list = &cur_chunk->next_;
|
||||
*location = chunk_list;
|
||||
}
|
||||
|
||||
// *chunk_list is ok to be NULL if adding at last location.
|
||||
return (nth == 0 || (count == nth - 1)) ? 1 : 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Chunk writer methods.
|
||||
|
||||
@@ -156,11 +135,12 @@ WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data,
|
||||
return WEBP_MUX_OK;
|
||||
}
|
||||
|
||||
WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
|
||||
uint32_t nth) {
|
||||
WebPMuxError ChunkSetHead(WebPChunk* const chunk,
|
||||
WebPChunk** const chunk_list) {
|
||||
WebPChunk* new_chunk;
|
||||
|
||||
if (!ChunkSearchListToSet(chunk_list, nth, &chunk_list)) {
|
||||
assert(chunk_list != NULL);
|
||||
if (*chunk_list != NULL) {
|
||||
return WEBP_MUX_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -168,11 +148,26 @@ WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
|
||||
if (new_chunk == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||
*new_chunk = *chunk;
|
||||
chunk->owner_ = 0;
|
||||
new_chunk->next_ = *chunk_list;
|
||||
new_chunk->next_ = NULL;
|
||||
*chunk_list = new_chunk;
|
||||
return WEBP_MUX_OK;
|
||||
}
|
||||
|
||||
WebPMuxError ChunkAppend(WebPChunk* const chunk,
|
||||
WebPChunk*** const chunk_list) {
|
||||
assert(chunk_list != NULL && *chunk_list != NULL);
|
||||
|
||||
if (**chunk_list == NULL) {
|
||||
ChunkSetHead(chunk, *chunk_list);
|
||||
} else {
|
||||
WebPChunk* last_chunk = **chunk_list;
|
||||
while (last_chunk->next_ != NULL) last_chunk = last_chunk->next_;
|
||||
ChunkSetHead(chunk, &last_chunk->next_);
|
||||
*chunk_list = &last_chunk->next_;
|
||||
}
|
||||
return WEBP_MUX_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Chunk deletion method(s).
|
||||
|
||||
|
Reference in New Issue
Block a user