summaryrefslogtreecommitdiff
path: root/core/fxcodec/lgif/fx_gif.cpp
diff options
context:
space:
mode:
authorNicolas Pena <npm@chromium.org>2017-05-16 18:30:24 -0400
committerChromium commit bot <commit-bot@chromium.org>2017-05-17 00:56:02 +0000
commit7876609b3540137663d48282ad94ba42a3749e73 (patch)
tree81c594651cb6a048ee61699a876dd12d5e471082 /core/fxcodec/lgif/fx_gif.cpp
parentb332581e185760597e8f0160011b1e6094634ed8 (diff)
downloadpdfium-7876609b3540137663d48282ad94ba42a3749e73.tar.xz
Gif: Detect string decoding errors
This CL adds some checks to make sure the DecodeString method does not go out out control: If code is equal to code_table[code].prefix, it will try to loop forever. Even if that's not the case, avoid reading a negative position from the stack. Bug: chromium:722672 Change-Id: I638f91542ba21f3a9915198fef853cc3cf94f4f1 Reviewed-on: https://pdfium-review.googlesource.com/5513 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Nicolás Peña <npm@chromium.org>
Diffstat (limited to 'core/fxcodec/lgif/fx_gif.cpp')
-rw-r--r--core/fxcodec/lgif/fx_gif.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp
index 0b56f3a509..5e257cc2f5 100644
--- a/core/fxcodec/lgif/fx_gif.cpp
+++ b/core/fxcodec/lgif/fx_gif.cpp
@@ -242,14 +242,18 @@ void CGifLZWDecoder::ClearTable() {
code_table[i].suffix = static_cast<uint8_t>(i);
}
-void CGifLZWDecoder::DecodeString(uint16_t code) {
+bool CGifLZWDecoder::DecodeString(uint16_t code) {
stack_size = 0;
while (code >= code_clear && code <= code_next) {
+ if (code == code_table[code].prefix || stack_size == GIF_MAX_LZW_CODE - 1)
+ return false;
+
stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = code_table[code].suffix;
code = code_table[code].prefix;
}
stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = static_cast<uint8_t>(code);
code_first = static_cast<uint8_t>(code);
+ return true;
}
void CGifLZWDecoder::AddCode(uint16_t prefix_code, uint8_t append_char) {
@@ -319,19 +323,30 @@ GifDecodeStatus CGifLZWDecoder::Decode(uint8_t* des_buf, uint32_t* des_size) {
if (code_next < GIF_MAX_LZW_CODE) {
if (code == code_next) {
AddCode(code_old, code_first);
- DecodeString(code);
+ if (!DecodeString(code)) {
+ strncpy(err_msg_ptr, "String Decoding Error",
+ GIF_MAX_ERROR_SIZE - 1);
+ return GifDecodeStatus::Error;
+ }
} else if (code > code_next) {
strncpy(err_msg_ptr, "Decode Error, Out Of Range",
GIF_MAX_ERROR_SIZE - 1);
return GifDecodeStatus::Error;
} else {
- DecodeString(code);
+ if (!DecodeString(code)) {
+ strncpy(err_msg_ptr, "String Decoding Error",
+ GIF_MAX_ERROR_SIZE - 1);
+ return GifDecodeStatus::Error;
+ }
uint8_t append_char = stack[GIF_MAX_LZW_CODE - stack_size];
AddCode(code_old, append_char);
}
}
} else {
- DecodeString(code);
+ if (!DecodeString(code)) {
+ strncpy(err_msg_ptr, "String Decoding Error", GIF_MAX_ERROR_SIZE - 1);
+ return GifDecodeStatus::Error;
+ }
}
code_old = code;
if (i + stack_size > *des_size) {