Add pdf_cjs_util_fuzzer. Expose some CJS_Util methods for testing. Disambiguate printx overloads for clarity. Change-Id: I6b85846078677ca3977924602ce4c1101827d486 Reviewed-on: https://pdfium-review.googlesource.com/c/45017 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp index 38dac89..261e464 100644 --- a/fxjs/cjs_publicmethods.cpp +++ b/fxjs/cjs_publicmethods.cpp
@@ -1365,7 +1365,7 @@ wsFormat = L"99999-9999"; break; case 2: - if (CJS_Util::printx(L"9999999999", wsSource).GetLength() >= 10) + if (CJS_Util::StringPrintx(L"9999999999", wsSource).GetLength() >= 10) wsFormat = L"(999) 999-9999"; else wsFormat = L"999-9999"; @@ -1375,7 +1375,7 @@ break; } - pEvent->Value() = CJS_Util::printx(wsFormat, wsSource); + pEvent->Value() = CJS_Util::StringPrintx(wsFormat, wsSource); return CJS_Result::Success(); }
diff --git a/fxjs/cjs_util.cpp b/fxjs/cjs_util.cpp index 6d883cc..2e77732 100644 --- a/fxjs/cjs_util.cpp +++ b/fxjs/cjs_util.cpp
@@ -55,6 +55,16 @@ #endif }; +enum CaseMode { kPreserveCase, kUpperCase, kLowerCase }; + +wchar_t TranslateCase(wchar_t input, CaseMode eMode) { + if (eMode == kLowerCase && FXSYS_iswupper(input)) + return input | 0x20; + if (eMode == kUpperCase && FXSYS_iswlower(input)) + return input & ~0x20; + return input; +} + } // namespace const JSMethodSpec CJS_Util::MethodSpecs[] = { @@ -258,23 +268,13 @@ return CJS_Result::Failure(JSMessage::kParamError); return CJS_Result::Success( - pRuntime->NewString(printx(pRuntime->ToWideString(params[0]), - pRuntime->ToWideString(params[1])) + pRuntime->NewString(StringPrintx(pRuntime->ToWideString(params[0]), + pRuntime->ToWideString(params[1])) .AsStringView())); } -enum CaseMode { kPreserveCase, kUpperCase, kLowerCase }; - -static wchar_t TranslateCase(wchar_t input, CaseMode eMode) { - if (eMode == kLowerCase && FXSYS_iswupper(input)) - return input | 0x20; - if (eMode == kUpperCase && FXSYS_iswlower(input)) - return input & ~0x20; - return input; -} - -WideString CJS_Util::printx(const WideString& wsFormat, - const WideString& wsSource) { +WideString CJS_Util::StringPrintx(const WideString& wsFormat, + const WideString& wsSource) { WideString wsResult; size_t iSourceIdx = 0; size_t iFormatIdx = 0;
diff --git a/fxjs/cjs_util.h b/fxjs/cjs_util.h index 917d797..87fd263 100644 --- a/fxjs/cjs_util.h +++ b/fxjs/cjs_util.h
@@ -26,8 +26,10 @@ CJS_Util(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime); ~CJS_Util() override; - static WideString printx(const WideString& cFormat, - const WideString& cSource); + // Exposed for testing. + static int ParseDataType(std::wstring* sFormat); + static WideString StringPrintx(const WideString& cFormat, + const WideString& cSource); JS_STATIC_METHOD(printd, CJS_Util); JS_STATIC_METHOD(printf, CJS_Util); @@ -36,13 +38,10 @@ JS_STATIC_METHOD(byteToChar, CJS_Util); private: - friend class CJS_Util_ParseDataType_Test; - static int ObjDefnID; static const char kName[]; static const JSMethodSpec MethodSpecs[]; - static int ParseDataType(std::wstring* sFormat); CJS_Result printd(CJS_Runtime* pRuntime, const std::vector<v8::Local<v8::Value>>& params);
diff --git a/testing/fuzzers/BUILD.gn b/testing/fuzzers/BUILD.gn index df4cac0..ccee96b 100644 --- a/testing/fuzzers/BUILD.gn +++ b/testing/fuzzers/BUILD.gn
@@ -38,6 +38,9 @@ ":pdf_xml_fuzzer_src", ":pdfium_fuzzer_src", ] + if (pdf_enable_v8) { + deps += [ ":pdf_cjs_util_fuzzer_src" ] + } if (pdf_enable_xfa) { deps += [ ":pdf_bidi_fuzzer_src", @@ -116,6 +119,17 @@ } } +if (pdf_enable_v8) { + pdfium_fuzzer("pdf_cjs_util_fuzzer_src") { + sources = [ + "pdf_cjs_util_fuzzer.cc", + ] + deps = [ + "../../fxjs", + ] + } +} + if (pdf_enable_xfa) { pdfium_fuzzer("pdf_bidi_fuzzer_src") { sources = [
diff --git a/testing/fuzzers/pdf_cjs_util_fuzzer.cc b/testing/fuzzers/pdf_cjs_util_fuzzer.cc new file mode 100644 index 0000000..a773244 --- /dev/null +++ b/testing/fuzzers/pdf_cjs_util_fuzzer.cc
@@ -0,0 +1,27 @@ +// Copyright 2018 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 <string> + +#include "core/fxcrt/widestring.h" +#include "fxjs/cjs_util.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + auto* short_data = reinterpret_cast<const unsigned short*>(data); + size_t short_size = size / sizeof(unsigned short); + if (short_size > 1) { + WideString input = WideString::FromUTF16LE(short_data, short_size); + std::wstring winput(input.c_str(), input.GetLength()); + CJS_Util::ParseDataType(&winput); + } + if (short_size > 2) { + size_t short_len1 = short_size / 2; + size_t short_len2 = short_size - short_len1; + WideString input1 = WideString::FromUTF16LE(short_data, short_len1); + WideString input2 = + WideString::FromUTF16LE(short_data + short_len1, short_len2); + CJS_Util::StringPrintx(input1, input2); + } + return 0; +}