Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1687)

Unified Diff: core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp

Issue 1930743003: Fix stack overflow from nested arrays. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: unsigned Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « core/fpdfapi/fpdf_page/fpdf_page_parser.cpp ('k') | core/fpdfapi/fpdf_page/pageint.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
index 47c0336ea94fa518dfd33d55e2270b31dd31f363..58ecb6c4d6a25b052c5055d0b14b363a55f6fe68 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp
@@ -31,6 +31,14 @@
#include "core/fxcrt/include/fx_ext.h"
#include "core/fxcrt/include/fx_safe_types.h"
+namespace {
+
+const uint32_t kMaxNestedArrayLevel = 512;
+const uint32_t kMaxWordBuffer = 256;
+const FX_STRSIZE kMaxStringLength = 32767;
+
+} // namespace
+
CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize) {
m_pBuf = pData;
m_Size = dwSize;
@@ -230,9 +238,6 @@ CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc,
return new CPDF_Stream(pData, dwStreamSize, pDict);
}
-#define MAX_WORD_BUFFER 256
-#define MAX_STRING_LENGTH 32767
-
CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() {
if (m_pLastObj) {
m_pLastObj->Release();
@@ -268,12 +273,12 @@ CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() {
if (PDFCharIsDelimiter(ch) && ch != '/') {
m_Pos--;
- m_pLastObj = ReadNextObject();
+ m_pLastObj = ReadNextObject(false, 0);
return Others;
}
while (1) {
- if (m_WordSize < MAX_WORD_BUFFER)
+ if (m_WordSize < kMaxWordBuffer)
m_WordBuffer[m_WordSize++] = ch;
if (!PDFCharIsNumeric(ch))
@@ -315,88 +320,90 @@ CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() {
return Keyword;
}
-CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray,
- FX_BOOL bInArray) {
+CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray,
+ uint32_t dwInArrayLevel) {
FX_BOOL bIsNumber;
GetNextWord(bIsNumber);
- if (m_WordSize == 0) {
- return NULL;
- }
+ if (!m_WordSize)
+ return nullptr;
+
if (bIsNumber) {
m_WordBuffer[m_WordSize] = 0;
return new CPDF_Number(CFX_ByteStringC(m_WordBuffer, m_WordSize));
}
+
int first_char = m_WordBuffer[0];
if (first_char == '/') {
return new CPDF_Name(
PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)));
}
- if (first_char == '(') {
+
+ if (first_char == '(')
return new CPDF_String(ReadString(), FALSE);
- }
+
if (first_char == '<') {
- if (m_WordSize == 1) {
+ if (m_WordSize == 1)
return new CPDF_String(ReadHexString(), TRUE);
- }
+
CPDF_Dictionary* pDict = new CPDF_Dictionary;
while (1) {
GetNextWord(bIsNumber);
- if (m_WordSize == 0) {
- pDict->Release();
- return nullptr;
- }
- if (m_WordSize == 2 && m_WordBuffer[0] == '>') {
+ if (m_WordSize == 2 && m_WordBuffer[0] == '>')
break;
- }
- if (m_WordBuffer[0] != '/') {
+
+ if (!m_WordSize || m_WordBuffer[0] != '/') {
pDict->Release();
return nullptr;
}
+
CFX_ByteString key =
PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1));
- CPDF_Object* pObj = ReadNextObject(TRUE);
+ CPDF_Object* pObj = ReadNextObject(true, 0);
if (!pObj) {
pDict->Release();
return nullptr;
}
- if (!key.IsEmpty()) {
- pDict->SetAt(key, pObj);
- } else {
+
+ if (key.IsEmpty())
pObj->Release();
- }
+ else
+ pDict->SetAt(key, pObj);
}
return pDict;
}
+
if (first_char == '[') {
- if (!bAllowNestedArray && bInArray) {
- return NULL;
+ if ((!bAllowNestedArray && dwInArrayLevel) ||
+ dwInArrayLevel > kMaxNestedArrayLevel) {
+ return nullptr;
}
+
CPDF_Array* pArray = new CPDF_Array;
while (1) {
- CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE);
+ CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, dwInArrayLevel + 1);
if (pObj) {
pArray->Add(pObj);
continue;
}
- if (m_WordSize == 0 || m_WordBuffer[0] == ']')
+ if (!m_WordSize || m_WordBuffer[0] == ']')
break;
}
return pArray;
}
+
+ if (m_WordSize == 5 && !memcmp(m_WordBuffer, "false", 5))
+ return new CPDF_Boolean(FALSE);
+
if (m_WordSize == 4) {
- if (memcmp(m_WordBuffer, "true", 4) == 0) {
+ if (memcmp(m_WordBuffer, "true", 4) == 0)
return new CPDF_Boolean(TRUE);
- }
- if (memcmp(m_WordBuffer, "null", 4) == 0) {
+
+ if (memcmp(m_WordBuffer, "null", 4) == 0)
return new CPDF_Null;
- }
- } else if (m_WordSize == 5) {
- if (memcmp(m_WordBuffer, "false", 5) == 0) {
- return new CPDF_Boolean(FALSE);
- }
}
- return NULL;
+
+ return nullptr;
}
void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) {
@@ -439,7 +446,7 @@ void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) {
return;
}
- if (m_WordSize < MAX_WORD_BUFFER)
+ if (m_WordSize < kMaxWordBuffer)
m_WordBuffer[m_WordSize++] = ch;
}
} else if (ch == '<') {
@@ -463,7 +470,7 @@ void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) {
}
while (1) {
- if (m_WordSize < MAX_WORD_BUFFER)
+ if (m_WordSize < kMaxWordBuffer)
m_WordBuffer[m_WordSize++] = ch;
if (!PDFCharIsNumeric(ch))
bIsNumber = FALSE;
@@ -492,8 +499,8 @@ CFX_ByteString CPDF_StreamParser::ReadString() {
case 0:
if (ch == ')') {
if (parlevel == 0) {
- if (buf.GetLength() > MAX_STRING_LENGTH) {
- return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);
+ if (buf.GetLength() > kMaxStringLength) {
+ return CFX_ByteString(buf.GetBuffer(), kMaxStringLength);
}
return buf.AsStringC();
}
@@ -571,8 +578,8 @@ CFX_ByteString CPDF_StreamParser::ReadString() {
if (PositionIsInBounds())
++m_Pos;
- if (buf.GetLength() > MAX_STRING_LENGTH) {
- return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);
+ if (buf.GetLength() > kMaxStringLength) {
+ return CFX_ByteString(buf.GetBuffer(), kMaxStringLength);
}
return buf.AsStringC();
}
@@ -605,8 +612,8 @@ CFX_ByteString CPDF_StreamParser::ReadHexString() {
if (!bFirst)
buf.AppendChar((char)code);
- if (buf.GetLength() > MAX_STRING_LENGTH)
- return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH);
+ if (buf.GetLength() > kMaxStringLength)
+ return CFX_ByteString(buf.GetBuffer(), kMaxStringLength);
return buf.AsStringC();
}
« no previous file with comments | « core/fpdfapi/fpdf_page/fpdf_page_parser.cpp ('k') | core/fpdfapi/fpdf_page/pageint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698