summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortsepez <tsepez@chromium.org>2016-08-18 14:37:07 -0700
committerCommit bot <commit-bot@chromium.org>2016-08-18 14:37:07 -0700
commit7996fe888cb98597cd1608af05fb59f45c837fc6 (patch)
treeecfcf15f788be1d2982a279de77d49d8e20a6c94
parent1a8946b09884393d7dc4941e59b3172a7e473b01 (diff)
downloadpdfium-7996fe888cb98597cd1608af05fb59f45c837fc6.tar.xz
Add llvm fuzzer for CPDF_PSEngine
Put class definition into its own header file so fuzzer can find it. Fix a pair of div by 0s immediately hit by the fuzzer. Review-Url: https://codereview.chromium.org/2253193003
-rw-r--r--core/fpdfapi/fpdf_page/cpdf_psengine.h100
-rw-r--r--core/fpdfapi/fpdf_page/fpdf_page_func.cpp95
-rw-r--r--testing/libfuzzer/BUILD.gn15
-rw-r--r--testing/libfuzzer/pdf_psengine_fuzzer.cc14
4 files changed, 137 insertions, 87 deletions
diff --git a/core/fpdfapi/fpdf_page/cpdf_psengine.h b/core/fpdfapi/fpdf_page/cpdf_psengine.h
new file mode 100644
index 0000000000..fc8badbe6d
--- /dev/null
+++ b/core/fpdfapi/fpdf_page/cpdf_psengine.h
@@ -0,0 +1,100 @@
+// Copyright 2016 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef CORE_FPDFAPI_FPDF_PAGE_CPDF_PSENGINE_H_
+#define CORE_FPDFAPI_FPDF_PAGE_CPDF_PSENGINE_H_
+
+#include <memory>
+#include <vector>
+
+#include "core/fxcrt/include/fx_system.h"
+
+class CPDF_PSEngine;
+class CPDF_PSOP;
+class CPDF_SimpleParser;
+
+enum PDF_PSOP {
+ PSOP_ADD,
+ PSOP_SUB,
+ PSOP_MUL,
+ PSOP_DIV,
+ PSOP_IDIV,
+ PSOP_MOD,
+ PSOP_NEG,
+ PSOP_ABS,
+ PSOP_CEILING,
+ PSOP_FLOOR,
+ PSOP_ROUND,
+ PSOP_TRUNCATE,
+ PSOP_SQRT,
+ PSOP_SIN,
+ PSOP_COS,
+ PSOP_ATAN,
+ PSOP_EXP,
+ PSOP_LN,
+ PSOP_LOG,
+ PSOP_CVI,
+ PSOP_CVR,
+ PSOP_EQ,
+ PSOP_NE,
+ PSOP_GT,
+ PSOP_GE,
+ PSOP_LT,
+ PSOP_LE,
+ PSOP_AND,
+ PSOP_OR,
+ PSOP_XOR,
+ PSOP_NOT,
+ PSOP_BITSHIFT,
+ PSOP_TRUE,
+ PSOP_FALSE,
+ PSOP_IF,
+ PSOP_IFELSE,
+ PSOP_POP,
+ PSOP_EXCH,
+ PSOP_DUP,
+ PSOP_COPY,
+ PSOP_INDEX,
+ PSOP_ROLL,
+ PSOP_PROC,
+ PSOP_CONST
+};
+
+constexpr uint32_t PSENGINE_STACKSIZE = 100;
+
+class CPDF_PSProc {
+ public:
+ CPDF_PSProc();
+ ~CPDF_PSProc();
+
+ FX_BOOL Parse(CPDF_SimpleParser* parser);
+ FX_BOOL Execute(CPDF_PSEngine* pEngine);
+
+ private:
+ std::vector<std::unique_ptr<CPDF_PSOP>> m_Operators;
+};
+
+class CPDF_PSEngine {
+ public:
+ CPDF_PSEngine();
+ ~CPDF_PSEngine();
+
+ FX_BOOL Parse(const FX_CHAR* str, int size);
+ FX_BOOL Execute();
+ FX_BOOL DoOperator(PDF_PSOP op);
+ void Reset() { m_StackCount = 0; }
+ void Push(FX_FLOAT value);
+ void Push(int value) { Push((FX_FLOAT)value); }
+ FX_FLOAT Pop();
+ uint32_t GetStackSize() const { return m_StackCount; }
+
+ private:
+ FX_FLOAT m_Stack[PSENGINE_STACKSIZE];
+ uint32_t m_StackCount;
+ CPDF_PSProc m_MainProc;
+};
+
+#endif // CORE_FPDFAPI_FPDF_PAGE_CPDF_PSENGINE_H_
diff --git a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
index ed8e6093d5..6a5bbacda5 100644
--- a/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
+++ b/core/fpdfapi/fpdf_page/fpdf_page_func.cpp
@@ -13,6 +13,7 @@
#include <utility>
#include <vector>
+#include "core/fpdfapi/fpdf_page/cpdf_psengine.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
@@ -21,58 +22,6 @@
#include "core/fxcrt/include/fx_safe_types.h"
#include "third_party/base/numerics/safe_conversions_impl.h"
-namespace {
-
-enum PDF_PSOP {
- PSOP_ADD,
- PSOP_SUB,
- PSOP_MUL,
- PSOP_DIV,
- PSOP_IDIV,
- PSOP_MOD,
- PSOP_NEG,
- PSOP_ABS,
- PSOP_CEILING,
- PSOP_FLOOR,
- PSOP_ROUND,
- PSOP_TRUNCATE,
- PSOP_SQRT,
- PSOP_SIN,
- PSOP_COS,
- PSOP_ATAN,
- PSOP_EXP,
- PSOP_LN,
- PSOP_LOG,
- PSOP_CVI,
- PSOP_CVR,
- PSOP_EQ,
- PSOP_NE,
- PSOP_GT,
- PSOP_GE,
- PSOP_LT,
- PSOP_LE,
- PSOP_AND,
- PSOP_OR,
- PSOP_XOR,
- PSOP_NOT,
- PSOP_BITSHIFT,
- PSOP_TRUE,
- PSOP_FALSE,
- PSOP_IF,
- PSOP_IFELSE,
- PSOP_POP,
- PSOP_EXCH,
- PSOP_DUP,
- PSOP_COPY,
- PSOP_INDEX,
- PSOP_ROLL,
- PSOP_PROC,
- PSOP_CONST
-};
-
-class CPDF_PSEngine;
-class CPDF_PSProc;
-
class CPDF_PSOP {
public:
explicit CPDF_PSOP(PDF_PSOP op) : m_op(op), m_value(0) {
@@ -105,39 +54,12 @@ class CPDF_PSOP {
std::unique_ptr<CPDF_PSProc> m_proc;
};
-class CPDF_PSProc {
- public:
- CPDF_PSProc() {}
- ~CPDF_PSProc() {}
-
- FX_BOOL Parse(CPDF_SimpleParser* parser);
- FX_BOOL Execute(CPDF_PSEngine* pEngine);
-
- private:
- std::vector<std::unique_ptr<CPDF_PSOP>> m_Operators;
-};
-
-const uint32_t PSENGINE_STACKSIZE = 100;
-
-class CPDF_PSEngine {
- public:
- CPDF_PSEngine();
- ~CPDF_PSEngine();
-
- FX_BOOL Parse(const FX_CHAR* str, int size);
- FX_BOOL Execute() { return m_MainProc.Execute(this); }
- FX_BOOL DoOperator(PDF_PSOP op);
- void Reset() { m_StackCount = 0; }
- void Push(FX_FLOAT value);
- void Push(int value) { Push((FX_FLOAT)value); }
- FX_FLOAT Pop();
- uint32_t GetStackSize() const { return m_StackCount; }
+FX_BOOL CPDF_PSEngine::Execute() {
+ return m_MainProc.Execute(this);
+}
- private:
- FX_FLOAT m_Stack[PSENGINE_STACKSIZE];
- uint32_t m_StackCount;
- CPDF_PSProc m_MainProc;
-};
+CPDF_PSProc::CPDF_PSProc() {}
+CPDF_PSProc::~CPDF_PSProc() {}
FX_BOOL CPDF_PSProc::Execute(CPDF_PSEngine* pEngine) {
for (size_t i = 0; i < m_Operators.size(); ++i) {
@@ -280,12 +202,12 @@ FX_BOOL CPDF_PSEngine::DoOperator(PDF_PSOP op) {
case PSOP_IDIV:
i2 = (int)Pop();
i1 = (int)Pop();
- Push(i1 / i2);
+ Push(i2 ? i1 / i2 : 0);
break;
case PSOP_MOD:
i2 = (int)Pop();
i1 = (int)Pop();
- Push(i1 % i2);
+ Push(i2 ? i1 % i2 : 0);
break;
case PSOP_NEG:
d1 = Pop();
@@ -538,7 +460,6 @@ FX_BOOL CPDF_PSFunc::v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const {
return TRUE;
}
-} // namespace
CPDF_SampledFunc::CPDF_SampledFunc() : CPDF_Function(Type::kType0Sampled) {}
diff --git a/testing/libfuzzer/BUILD.gn b/testing/libfuzzer/BUILD.gn
index 1b7a7fb456..718a1db3c0 100644
--- a/testing/libfuzzer/BUILD.gn
+++ b/testing/libfuzzer/BUILD.gn
@@ -168,3 +168,18 @@ source_set("pdf_jpx_fuzzer") {
":libfuzzer_config",
]
}
+
+source_set("pdf_psengine_fuzzer") {
+ testonly = true
+ sources = [
+ "pdf_psengine_fuzzer.cc",
+ ]
+ deps = [
+ "//third_party/pdfium:pdfium",
+ ]
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [
+ "//build/config/compiler:no_chromium_code",
+ ":libfuzzer_config",
+ ]
+}
diff --git a/testing/libfuzzer/pdf_psengine_fuzzer.cc b/testing/libfuzzer/pdf_psengine_fuzzer.cc
new file mode 100644
index 0000000000..89f582ec64
--- /dev/null
+++ b/testing/libfuzzer/pdf_psengine_fuzzer.cc
@@ -0,0 +1,14 @@
+// Copyright 2016 The PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fpdfapi/fpdf_page/cpdf_psengine.h"
+
+#include <cstdint>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ CPDF_PSEngine engine;
+ if (engine.Parse(reinterpret_cast<const char*>(data), size))
+ engine.Execute();
+ return 0;
+}