test: move fuzzing tests from google/oss-fuzz repository (#4719)

This commit is contained in:
tyler92 2024-10-10 14:30:10 +03:00 committed by GitHub
parent c038b52f36
commit aa0faed54f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 857 additions and 0 deletions

View File

@ -212,6 +212,9 @@ option(ENABLE_COMPILER_WARNINGS
option(ENABLE_SAMPLES
"Set to OFF|ON (default is OFF) to control build of POCO samples" OFF)
option(ENABLE_FUZZING
"Set to OFF|ON (default is OFF) to control build of fuzzing targets for oss-fuzz (Clang compiler is required)" OFF)
option(POCO_UNBUNDLED
"Set to OFF|ON (default is OFF) to control linking dependencies as external" OFF)
@ -226,6 +229,14 @@ else()
message(STATUS "Building without tests & samples")
endif()
if(ENABLE_FUZZING)
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message(FATAL_ERROR "ENABLE_FUZZING flag requires using Clang compiler")
else()
message(STATUS "Building fuzzing test targets with engine $ENV{LIB_FUZZING_ENGINE}")
endif()
endif()
if(POCO_UNBUNDLED)
message(STATUS "Using external sqlite, zlib, pcre2, expat, libpng, ...")
else()

View File

@ -242,3 +242,7 @@ if(ENABLE_TESTS)
endif()
add_subdirectory(testsuite)
endif()
if(ENABLE_FUZZING)
add_subdirectory(fuzzing)
endif()

View File

@ -0,0 +1,7 @@
add_executable(Foundation-datetime-fuzzer DateTimeParse.cpp)
target_link_libraries(Foundation-datetime-fuzzer PUBLIC Poco::Foundation)
set_target_properties(Foundation-datetime-fuzzer PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE})
add_executable(Foundation-misc-fuzzer MiscFuzzing.cpp)
target_link_libraries(Foundation-misc-fuzzer PUBLIC Poco::Foundation)
set_target_properties(Foundation-misc-fuzzer PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE})

View File

@ -0,0 +1,46 @@
#include "Poco/DateTimeParser.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/DateTimeFormatter.h"
using namespace Poco;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
const std::string input(reinterpret_cast<const char*>(data), size);
const std::string formats[] = {
DateTimeFormat::ISO8601_FORMAT,
DateTimeFormat::ISO8601_FRAC_FORMAT,
DateTimeFormat::RFC822_FORMAT,
DateTimeFormat::RFC1123_FORMAT,
DateTimeFormat::HTTP_FORMAT,
DateTimeFormat::RFC850_FORMAT,
DateTimeFormat::RFC1036_FORMAT,
DateTimeFormat::ASCTIME_FORMAT,
DateTimeFormat::SORTABLE_FORMAT,
"%m/%d/%y %h:%M %a",
"T%H:%M:%F",
};
int tzd = 0;
DateTime dt;
for (const auto& format : formats)
{
DateTimeParser::tryParse(format, input, dt, tzd);
DateTimeFormatter::format(dt.timestamp(), format, tzd);
}
dt.makeLocal(tzd);
dt.makeUTC(tzd);
try
{
dt = DateTimeParser::parse(input, tzd);
}
catch (const std::exception&)
{
}
return 0;
}

View File

@ -0,0 +1,95 @@
#include "Poco/URI.h"
#include "Poco/Path.h"
#include "Poco/UUID.h"
#include "Poco/UTF8String.h"
#include <fuzzer/FuzzedDataProvider.h>
using namespace Poco;
static void fuzzURI(FuzzedDataProvider& dataProvider)
{
try
{
URI uri1(dataProvider.ConsumeRandomLengthString());
URI uri2(uri1, dataProvider.ConsumeRandomLengthString());
URI uri3(uri2);
uri3.normalize();
uri3.setQueryParameters(uri1.getQueryParameters());
uri2 = uri3.toString();
}
catch (const std::exception&)
{
}
}
static void fuzzPath(FuzzedDataProvider& dataProvider)
{
try
{
Path path1;
path1.tryParse(dataProvider.ConsumeRandomLengthString());
Path path2(path1, Path(dataProvider.ConsumeRandomLengthString()));
Path path3 = path1.absolute();
Path path4 = Path::expand(dataProvider.ConsumeRandomLengthString());
const auto style1 = dataProvider.ConsumeIntegralInRange<char>(Path::PATH_UNIX, Path::PATH_GUESS);
const auto style2 = dataProvider.ConsumeIntegralInRange<char>(Path::PATH_UNIX, Path::PATH_GUESS);
path3.assign(path4.toString(static_cast<Path::Style>(style1)), static_cast<Path::Style>(style2));
}
catch (const std::exception&)
{
}
}
static void fuzzUUID(FuzzedDataProvider& dataProvider)
{
try
{
UUID uuid1(dataProvider.ConsumeRandomLengthString());
UUID uuid2(uuid1.toString());
uuid2.tryParse(dataProvider.ConsumeRandomLengthString());
}
catch (const std::exception&)
{
}
}
static void fuzzUTF8String(FuzzedDataProvider& dataProvider)
{
try
{
auto str1 = UTF8::unescape(dataProvider.ConsumeRandomLengthString());
auto str2 = UTF8::escape(str1);
UTF8::toUpperInPlace(str1);
UTF8::toLowerInPlace(str2);
}
catch (const std::exception&)
{
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
FuzzedDataProvider dataProvider(data, size);
switch (dataProvider.ConsumeIntegral<char>())
{
case 0:
fuzzURI(dataProvider);
break;
case 1:
fuzzPath(dataProvider);
break;
case 2:
fuzzUUID(dataProvider);
break;
case 3:
fuzzUTF8String(dataProvider);
break;
}
return 0;
}

View File

@ -48,3 +48,7 @@ endif()
if(ENABLE_TESTS)
add_subdirectory(testsuite)
endif()
if(ENABLE_FUZZING)
add_subdirectory(fuzzing)
endif()

View File

@ -0,0 +1,3 @@
add_executable(JSON-parse-fuzzer JsonParse.cpp)
target_link_libraries(JSON-parse-fuzzer PUBLIC Poco::JSON)
set_target_properties(JSON-parse-fuzzer PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE})

View File

@ -0,0 +1,26 @@
#include "Poco/JSON/Parser.h"
using namespace Poco;
using namespace Poco::JSON;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
std::string json(reinterpret_cast<const char*>(data), size);
Parser parser;
Dynamic::Var result;
try
{
result = parser.parse(json);
}
catch (Exception& e)
{
return 0;
}
catch (const std::exception& e)
{
return 0;
}
return 0;
}

View File

@ -35,3 +35,7 @@ POCO_GENERATE_PACKAGE(JWT)
if(ENABLE_TESTS)
add_subdirectory(testsuite)
endif()
if(ENABLE_FUZZING)
add_subdirectory(fuzzing)
endif()

View File

@ -0,0 +1,3 @@
add_executable(JWT-decode-fuzzer JWTDecode.cpp)
target_link_libraries(JWT-decode-fuzzer PUBLIC Poco::JWT)
set_target_properties(JWT-decode-fuzzer PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE})

47
JWT/fuzzing/JWTDecode.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "Poco/JWT/Token.h"
#include "Poco/JWT/Signer.h"
using namespace Poco;
using namespace Poco::JWT;
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
{
Crypto::initializeCrypto();
return 0;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
const std::string input(reinterpret_cast<const char*>(data), size);
Signer signer;
signer.addAllAlgorithms();
signer.setHMACKey("secret");
try
{
// verify untrusted input
Token token;
token = signer.verify(input);
}
catch (const Exception&)
{
}
for (const auto& algorithm : signer.getAlgorithms())
{
try
{
// sign and verify again
Token token(input);
token.setAudience(token.getAudience());
signer.sign(token, algorithm);
token = signer.verify(token.toString());
}
catch (const Exception&)
{
}
}
return 0;
}

View File

@ -75,3 +75,6 @@ if(ENABLE_TESTS)
add_subdirectory(testsuite)
endif()
if(ENABLE_FUZZING)
add_subdirectory(fuzzing)
endif()

View File

@ -0,0 +1,8 @@
add_executable(Net-mail-parser-fuzzer MailParse.cpp)
target_link_libraries(Net-mail-parser-fuzzer PUBLIC Poco::Net)
set_target_properties(Net-mail-parser-fuzzer PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE})
add_executable(Net-http-parser-fuzzer HTTPParse.cpp)
target_link_libraries(Net-http-parser-fuzzer PUBLIC Poco::Net)
set_target_properties(Net-http-parser-fuzzer PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE})

96
Net/fuzzing/HTTPParse.cpp Normal file
View File

@ -0,0 +1,96 @@
#include "Poco/MemoryStream.h"
#include "Poco/Net/EscapeHTMLStream.h"
#include "Poco/Net/HTMLForm.h"
#include "Poco/Net/HTTPCredentials.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/OAuth10Credentials.h"
#include "Poco/Net/OAuth20Credentials.h"
#include "Poco/Net/DNS.h"
#include "Poco/NullStream.h"
using namespace Poco;
using namespace Poco::Net;
template <class F>
void catchExceptions(const F& func)
{
try
{
func();
}
catch (const std::exception&)
{
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
NullOutputStream null;
// HTTPRequest parsing
catchExceptions(
[&]
{
MemoryInputStream stream(reinterpret_cast<const char*>(data), size);
HTTPRequest request;
request.read(stream);
request.write(null);
HTTPCredentials creds;
creds.fromURI(URI(request.getURI()));
creds.updateAuthInfo(request);
creds.updateProxyAuthInfo(request);
});
// HTTPResponse parsing
catchExceptions(
[&]
{
MemoryInputStream stream(reinterpret_cast<const char*>(data), size);
HTTPResponse response;
response.read(stream);
response.write(null);
HTTPRequest request(HTTPRequest::HTTP_GET, "/");
request.setHost(DNS::encodeIDN(DNS::decodeIDN(response.get(HTTPRequest::HOST))));
HTTPCredentials creds;
creds.authenticate(request, response);
creds.proxyAuthenticate(request, response);
});
// OAuth10Credentials
catchExceptions(
[&]
{
MemoryInputStream stream(reinterpret_cast<const char*>(data), size);
HTTPRequest request;
request.read(stream);
EscapeHTMLOutputStream htmlStream(null);
HTMLForm form(request, stream);
form.prepareSubmit(request);
form.write(htmlStream);
OAuth10Credentials oauth10(request);
oauth10.verify(request, URI(request.getURI()), form);
oauth10.authenticate(request, URI(request.getURI()), form,
request.hasToken("X-Method", "Plain") ? OAuth10Credentials::SIGN_PLAINTEXT
: OAuth10Credentials::SIGN_HMAC_SHA1);
});
// OAuth20Credentials
catchExceptions(
[&]
{
MemoryInputStream stream(reinterpret_cast<const char*>(data), size);
HTTPRequest request;
request.read(stream);
OAuth20Credentials oauth20(request);
oauth20.authenticate(request);
});
return 0;
}

30
Net/fuzzing/MailParse.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "Poco/MemoryStream.h"
#include "Poco/Net/MailMessage.h"
#include "Poco/Net/MailStream.h"
#include "Poco/NullStream.h"
using namespace Poco;
using namespace Poco::Net;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
try
{
MemoryInputStream stream(reinterpret_cast<const char*>(data), size);
MailInputStream mis(stream);
MailMessage mail;
mail.read(mis);
MailRecipient recipient(MailRecipient::CC_RECIPIENT, MailMessage::encodeWord(mail.getSender()));
mail.addRecipient(recipient);
NullOutputStream null;
MailOutputStream mos(null);
mail.write(mos);
}
catch (const std::exception&)
{
}
return 0;
}

View File

@ -0,0 +1,8 @@
HTTP/1.0 401 Unauthorized
Server: HTTPd/0.9
Host: localhost
Date: Sun, 10 Apr 2014 20:26:47 GMT
WWW-Authenticate: Basic realm=<realm>, charset="UTF-8"
Proxy-Authenticate: Basic realm=<realm>, charset="UTF-8"

View File

@ -0,0 +1,11 @@
HTTP/1.1 401 Unauthorized
Content-Length: 0
Server: Microsoft-HTTPAPI/2.0
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
Proxy-Authenticate: Negotiate
Proxy-Authenticate: NTLM
Date: Tue, 10 Aug 2021 07:38:46 GMT
Proxy-Support: Session-Based-Authentication

View File

@ -0,0 +1,27 @@
HTTP/1.0 401 Unauthorized
Server: HTTPd/0.9
Host: google
Date: Sun, 10 Apr 2014 20:26:47 GMT
WWW-Authenticate: Digest realm="testrealm@host.com",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
Proxy-Authenticate: Digest realm="testrealm@host.com",
qop="auth,auth-int",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
Content-Type: text/html
Content-Length: 153
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Error</title>
</head>
<body>
<h1>401 Unauthorized.</h1>
</body>
</html>

View File

@ -0,0 +1,3 @@
HTTP/1.1 401 Unauthorized
WWW-Authenticate: NTLM

View File

@ -0,0 +1,4 @@
HTTP/1.1 401 Unauthorized
Host: localhost
WWW-Authenticate: NTLM TlRMTVNTUAACAAAAEAAQADgAAAAFgooCTBz0AAAAAAAAAAAAAAAAAAAAAAKAAAABYAoAAQAAAASERUVUQQ==

View File

@ -0,0 +1,4 @@
GET /protected-resource HTTP/1.1
Host: example.com
Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==

View File

@ -0,0 +1,4 @@
GET /protected-resource HTTP/1.1
Host: example.com
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAHgAAABMAUwB0AAAABQAFACoAAAAMAAwAVAAQAAAAGAAYAGQAAABAAEABMAAAAIgAiAHAAAAAAAAAAAAAAAwAAAAAYAIgBnlgMiYmCdgYmJnPwAAAAAAAAAAAAAAAAAAAAADAB8AVAByAGkAZQBkAEUAAADAAAAA

View File

@ -0,0 +1,7 @@
HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
[page content]

View File

@ -0,0 +1,12 @@
POST /oauth1/access HTTP/1.1
Host: server.example.com
Authorization: OAuth realm="Example",
oauth_consumer_key="jd83jd92dhsh93js",
oauth_token="hdk48Djdsa",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="123456789",
oauth_nonce="7d8f3e4a",
oauth_verifier="473f82d3",
oauth_signature="..."

View File

@ -0,0 +1,5 @@
POST /resource/1/update HTTP/1.1
Authorization: Bearer RsT5OjbzRn430zqMLgV3Ia"
Host: api.authorization-server.com
description=Hello+World

View File

@ -0,0 +1,6 @@
GET / HTTP/1.1
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Proxy-Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Host: QWxhZGRpbjpvcGVuIHNlc2FtZQ==

View File

@ -0,0 +1,29 @@
POST /cgi-bin/qtest HTTP/1.1
Host: aram
User-Agent: Mozilla/5.0 Gecko/2009042316 Firefox/3.0.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://aram/~martind/banner.htm
Content-Type: multipart/form-data; boundary=2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f
Content-Length: 514
--2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f
Content-Disposition: form-data; name="datafile1"; filename="r.gif"
Content-Type: image/gif
GIF87a.............,...........D..;
--2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f
Content-Disposition: form-data; name="datafile2"; filename="g.gif"
Content-Type: image/gif
GIF87a.............,...........D..;
--2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f
Content-Disposition: form-data; name="datafile3"; filename="b.gif"
Content-Type: image/gif
GIF87a.............,...........D..;
--2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f--

View File

@ -0,0 +1,22 @@
GET /dir/index.html HTTP/1.0
Host: localhost
Authorization: Digest username="Mufasa",
realm="testrealm@host.com",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri="/dir/index.html",
qop=auth,
nc=00000001,
cnonce="0a4f113b",
response="6629fae49393a05397450978507c4ef1",
opaque="5ccc069c403ebaf9f0171e9517f40e41"
Proxy-Authorization: Digest username="Mufasa",
realm="testrealm@host.com",
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri="/dir/index.html",
qop=auth,
nc=00000001,
cnonce="0a4f113b",
response="6629fae49393a05397450978507c4ef1",
opaque="5ccc069c403ebaf9f0171e9517f40e41"

View File

@ -0,0 +1,2 @@
GET / HTTP/1.1
Header: =?UTF32?B?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe///////////xxxxxxxxxxx?=

View File

@ -0,0 +1,4 @@
GET http://example.com/ HTTP/1.1
Host: example.com
Proxy-Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==

View File

@ -0,0 +1,22 @@
From: sender@example.com
To: recipient@example.com
Subject: =?CP1251?B?T2zpcg==?=
Content-Type: multipart/alternative; boundary="boundary-string"
--your-boundary
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Plain text email goes here!
This is the fallback if email client does not support HTML
--boundary-string
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
<h1>This is the HTML Section!</h1>
<p>This is what displays in most modern email clients</p>
--boundary-string--

View File

@ -0,0 +1,30 @@
From: Some One <some.one@example.org>
To: Someone Else <someone.else@example.org>
Subject: =?MacChineseTrad?B?T2zpcg==?=
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=zxnrbl
This is the preamble.
--zxnrbl
Content-Type: multipart/alternative; boundary=xyzzy
This is the nested preamble.
--xyzzy
Content-Type: text/plain
Hello!
--xyzzy
Content-Type: text/html
<p>Hello!</p>
--xyzzy--
This is the nested epilogue.
--zxnrbl
Content-Type: text/plain
Content-Disposition: attachment; filename="attachment.txt"
This is the attachment.
--zxnrbl--
This is the epilogue.

View File

@ -0,0 +1,9 @@
From: sender@example.com
To: recipient@example.com
Subject: =?ISO-8859-1?B?T2zpcg==?=
Date: Tue, 1 Oct 2024 10:00:00 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 7bit
Hello

View File

@ -0,0 +1,13 @@
From: sender@example.com
To: recipient@example.com
Content-Type: multipart/mixed; boundary="boundary"
--boundary
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: base64
SGVsbG8gdGhlcmUsCgpUaGlzIGlzIGEgc2FtcGxlIGVtYWlsIHdpdGggYmFzZTY0IGVuY29kaW5n
IGFuZCBhbiBhdHRhY2htZW50LgoKLS0gU2VuZGVy
--boundary--

View File

@ -0,0 +1,9 @@
From: sender@example.com
To: recipient@example.com
Subject: =?UTF-8?B?44GT44KT44Gr44Gh44Gv?=
Date: Tue, 1 Oct 2024 10:00:00 +0000
MIME-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
Hello

View File

@ -73,3 +73,6 @@ if(ENABLE_TESTS)
add_subdirectory(testsuite)
endif()
if(ENABLE_FUZZING)
add_subdirectory(fuzzing)
endif()

View File

@ -0,0 +1,3 @@
add_executable(XML-parse-fuzzer XMLParse.cpp)
target_link_libraries(XML-parse-fuzzer PUBLIC Poco::XML)
set_target_properties(XML-parse-fuzzer PROPERTIES LINK_FLAGS $ENV{LIB_FUZZING_ENGINE})

88
XML/fuzzing/XMLParse.cpp Normal file
View File

@ -0,0 +1,88 @@
#include "Poco/AutoPtr.h"
#include "Poco/DOM/DOMParser.h"
#include "Poco/DOM/Document.h"
#include "Poco/SAX/DefaultHandler.h"
#include "Poco/SAX/SAXParser.h"
#include "Poco/XML/XMLStreamParser.h"
using namespace Poco;
using namespace Poco::XML;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
std::string xml(reinterpret_cast<const char*>(data), size);
// SAX Parser
SAXParser saxParser;
std::uint8_t saxFeatures = size > 0 ? data[size - 1] : 0;
DefaultHandler defHandler;
saxParser.setContentHandler(&defHandler);
saxParser.setDTDHandler(&defHandler);
saxParser.setErrorHandler(&defHandler);
saxParser.setEntityResolver(&defHandler);
for (const auto feature : {
XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES,
XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES,
XMLReader::FEATURE_NAMESPACES,
XMLReader::FEATURE_NAMESPACE_PREFIXES,
SAXParser::FEATURE_PARTIAL_READS,
})
{
saxParser.setFeature(feature, saxFeatures & 0x01);
saxFeatures >>= 1;
}
try
{
saxParser.parseString(xml);
}
catch (const std::exception&)
{
}
// DOM Parser
DOMParser domParser;
std::uint8_t domFeatures = size > 0 ? data[size - 1] : 0;
for (const auto feature : {
XMLReader::FEATURE_EXTERNAL_GENERAL_ENTITIES,
XMLReader::FEATURE_EXTERNAL_PARAMETER_ENTITIES,
XMLReader::FEATURE_NAMESPACES,
XMLReader::FEATURE_NAMESPACE_PREFIXES,
DOMParser::FEATURE_FILTER_WHITESPACE,
})
{
domParser.setFeature(feature, domFeatures & 0x01);
domFeatures >>= 1;
}
try
{
Poco::AutoPtr<Document> doc = domParser.parseString(xml);
}
catch (const std::exception&)
{
}
// Stream Parser
std::istringstream stream(xml);
try
{
XMLStreamParser streamParser(stream, "fuzz");
for (XMLStreamParser::EventType e : streamParser)
{
streamParser.getQName().toString();
}
}
catch (const std::exception&)
{
}
return 0;
}

116
XML/fuzzing/xml.dict Normal file
View File

@ -0,0 +1,116 @@
attr_encoding=" encoding=\"1\""
attr_generic=" a=\"1\""
attr_href=" href=\"1\""
attr_standalone=" standalone=\"no\""
attr_version=" version=\"1\""
attr_xml_base=" xml:base=\"1\""
attr_xml_id=" xml:id=\"1\""
attr_xml_lang=" xml:lang=\"1\""
attr_xml_space=" xml:space=\"1\""
attr_xmlns=" xmlns=\"1\""
entity_builtin="&lt;"
entity_decimal="&#1;"
entity_external="&a;"
entity_hex="&#x1;"
# keywords
"ANY"
"ATTLIST"
"CDATA"
"DOCTYPE"
"ELEMENT"
"EMPTY"
"ENTITIES"
"ENTITY"
"FIXED"
"ID"
"IDREF"
"IDREFS"
"IGNORE"
"IMPLIED"
"INCLUDE"
"NDATA"
"NMTOKEN"
"NMTOKENS"
"NOTATION"
"PCDATA"
"PUBLIC"
"REQUIRED"
"SYSTEM"
# Various tag parts
"<"
">"
"/>"
"</"
"<?"
"?>"
"<!"
"!>"
"[]"
"]]"
"<![CDATA["
"<![CDATA[]]>"
"\"\""
"''"
"=\"\""
"=''"
# DTD
"<!ATTLIST"
"<!DOCTYPE"
"<!ELEMENT"
"<!ENTITY"
"<![IGNORE["
"<![INCLUDE["
"<!NOTATION"
"#CDATA"
"#FIXED"
"#IMPLIED"
"#PCDATA"
"#REQUIRED"
# Encodings
"ISO-8859-1"
"US-ASCII"
"UTF-8"
"UTF-16"
"UTF-16BE"
"UTF-16LE"
# Namespaces and schemas
"xmlns"
"xmlns:"
"xmlns:xhtml=\"http://www.w3.org/1999/xhtml\""
"xmlns:xml=\"http://www.w3.org/XML/1998/namespace\""
"xmlns:xmlns=\"http://www.w3.org/2000/xmlns\""
string_col_fallback=":fallback"
string_col_generic=":a"
string_col_include=":include"
string_dashes="--"
string_parentheses="()"
string_percent="%a"
string_schema=":schema"
string_ucs4="UCS-4"
tag_close="</a>"
tag_open="<a>"
tag_open_close="<a />"
"<?xml?>"
"http://docboo"
"http://www.w"
"he30"
"he2"
"IET"
"FDF-10"
"aDUCS-4OPveb:"
"a>"
"UT"
"xMl"
"/usr/share/sg"
"ha07"
"http://www.oa"
"cle"

29
build/script/oss-fuzz-build.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash -eu
mkdir -p cmake-build
cd cmake-build
cmake -DBUILD_SHARED_LIBS=OFF -DENABLE_TESTS=OFF -DENABLE_FUZZING=ON \
-DENABLE_ACTIVERECORD=OFF -DENABLE_PAGECOMPILER=OFF \
-DENABLE_PAGECOMPILER_FILE2PAGE=OFF -DENABLE_DATA_SQLITE=OFF \
-DENABLE_REDIS=OFF -DENABLE_MONGODB=OFF -DENABLE_PROMETHEUS=OFF \
-DENABLE_ACTIVERECORD_COMPILER=OFF \
..
make -j$(nproc)
# Copy binaries with preserving historical names
cp bin/JSON-parse-fuzzer $OUT/json_parser_fuzzer
cp bin/XML-parse-fuzzer $OUT/xml_parser_fuzzer
cp bin/Foundation-datetime-fuzzer $OUT/date_time_fuzzer
cp bin/Foundation-misc-fuzzer $OUT/foundation_misc_fuzzer
cp bin/JWT-decode-fuzzer $OUT/jwt_decode_fuzzer
cp bin/Net-mail-parser-fuzzer $OUT/mail_message_fuzzer
cp bin/Net-http-parser-fuzzer $OUT/http_message_fuzzer
# Seed corpus
zip -q -r -j $OUT/mail_message_fuzzer_seed_corpus.zip $SRC/poco/Net/fuzzing/seed/Mail
zip -q -r -j $OUT/http_message_fuzzer_seed_corpus.zip $SRC/poco/Net/fuzzing/seed/HTTP
# Dictionaries
cp $SRC/poco/XML/fuzzing/xml.dict $OUT/xml_parser_fuzzer.dict