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

Unified Diff: core/src/fxcrt/extension.h

Issue 322333002: Fix the potential integer overflow from "offset + size" (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 6 years, 5 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
Index: core/src/fxcrt/extension.h
diff --git a/core/src/fxcrt/extension.h b/core/src/fxcrt/extension.h
index a736425d57336862a1f5a9617561a53825591e91..8931eaa600cff53c25198c0a5b9acc65015a7536 100644
--- a/core/src/fxcrt/extension.h
+++ b/core/src/fxcrt/extension.h
@@ -6,6 +6,9 @@
#ifndef _FXCRT_EXTENSION_IMP_
#define _FXCRT_EXTENSION_IMP_
+
+#include "../../../third_party/numerics/safe_math.h"
+
class IFXCRT_FileAccess
{
public:
@@ -181,9 +184,13 @@ public:
}
virtual FX_BOOL SetRange(FX_FILESIZE offset, FX_FILESIZE size)
{
- if (offset < 0 || (size_t)(offset + size) > m_nCurSize) {
+ base::CheckedNumeric<FX_FILESIZE> range = size;
+ range += size;
palmer 2014/07/23 17:58:36 BUG: The original code checked offset + size, but
jun_fang 2014/07/24 07:14:39 This issue was reported in the original bug.
+
+ if (!range.IsValid() || offset <= 0 || size <= 0 || range.ValueOrDie() > m_nCurSize) {
return FALSE;
}
+
m_nOffset = (size_t)offset, m_nSize = (size_t)size;
m_bUseRange = TRUE;
m_nCurPos = m_nOffset;
@@ -198,13 +205,24 @@ public:
if (!buffer || !size) {
return FALSE;
}
+
+ base::CheckedNumeric<FX_FILESIZE> safeOffset = offset;
if (m_bUseRange) {
- offset += (FX_FILESIZE)m_nOffset;
+ safeOffset += m_nOffset;
}
- if ((size_t)offset + size > m_nCurSize) {
+
+ if (!safeOffset.IsValid())
+ return FALSE;
+
+ offset = safeOffset.ValueOrDie();
+
+ base::CheckedNumeric<size_t> newPos = size;
+ newPos += offset;
+ if (newPos.ValueOrDefault(0) == 0 || newPos.ValueOrDie() > m_nCurSize) {
palmer 2014/07/23 17:58:36 ValueOrDie will cause a program abort, and you'll
jun_fang 2014/07/24 07:14:39 Will update.
jschuh 2014/07/24 13:48:46 You can skip the !newPos.IsValid() check, because
return FALSE;
}
- m_nCurPos = (size_t)offset + size;
+
+ m_nCurPos = newPos.ValueOrDie();
if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
FXSYS_memcpy32(buffer, (FX_LPBYTE)m_Blocks[0] + (size_t)offset, size);
return TRUE;
@@ -250,7 +268,12 @@ public:
offset += (FX_FILESIZE)m_nOffset;
}
if (m_dwFlags & FX_MEMSTREAM_Consecutive) {
- m_nCurPos = (size_t)offset + size;
+ base::CheckedNumeric<size_t> newPos = size;
+ newPos += offset;
+ if (!newPos.IsValid())
+ return FALSE;
+
+ m_nCurPos = newPos.ValueOrDie();
if (m_nCurPos > m_nTotalSize) {
m_nTotalSize = (m_nCurPos + m_nGrowSize - 1) / m_nGrowSize * m_nGrowSize;
if (m_Blocks.GetSize() < 1) {
@@ -270,10 +293,16 @@ public:
}
return TRUE;
}
- if (!ExpandBlocks((size_t)offset + size)) {
+
+ base::CheckedNumeric<size_t> newPos = size;
+ newPos += offset;
+ if (!newPos.IsValid())
+ return FALSE;
+
+ if (!ExpandBlocks(newPos.ValueOrDie())) {
return FALSE;
}
- m_nCurPos = (size_t)offset + size;
+ m_nCurPos = newPos.ValueOrDie();
size_t nStartBlock = (size_t)offset / m_nGrowSize;
offset -= (FX_FILESIZE)(nStartBlock * m_nGrowSize);
while (size) {

Powered by Google App Engine
This is Rietveld 408576698