--- /dev/null
+fuzzer: $(PHP_FUZZER_BINARIES)
+
+FUZZER_BUILD = $(LIBTOOL) --mode=link $(FUZZING_CC) -export-dynamic $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(EXTRA_LDFLAGS_PROGRAM) $(LDFLAGS) $(PHP_RPATHS) $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(EXTRA_LIBS) $(ZEND_EXTRA_LIBS) $(FUZZING_LIB) -rpath /ORIGIN/lib
+
+$(SAPI_FUZZER_PATH)/php-fuzz-parser: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP_FUZZER_PARSER_OBJS)
+ $(FUZZER_BUILD) $(PHP_FUZZER_PARSER_OBJS) -o $@
+
+$(SAPI_FUZZER_PATH)/php-fuzz-unserialize: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP_FUZZER_UNSERIALIZE_OBJS)
+ $(FUZZER_BUILD) $(PHP_FUZZER_UNSERIALIZE_OBJS) -o $@
+
+$(SAPI_FUZZER_PATH)/php-fuzz-json: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP_FUZZER_JSON_OBJS)
+ $(FUZZER_BUILD) $(PHP_FUZZER_JSON_OBJS) -o $@
+
+$(SAPI_FUZZER_PATH)/php-fuzz-exif: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP_FUZZER_EXIF_OBJS)
+ $(FUZZER_BUILD) $(PHP_FUZZER_EXIF_OBJS) -o $@
+
+$(SAPI_FUZZER_PATH)/php-fuzz-mbstring: $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) $(PHP_FUZZER_MBSTRING_OBJS)
+ $(FUZZER_BUILD) $(PHP_FUZZER_MBSTRING_OBJS) -o $@
--- /dev/null
+Fuzzing SAPI for PHP
+
+Enable fuzzing targets with --enable-fuzzer switch.
+
+Your compiler should support -fsanitize=address and you need
+to have Fuzzer library around.
+
+When running `make` it creates these binaries in `sapi/fuzzer/`:
+* php-fuzz-parser - fuzzing language parser
+* php-fuzz-unserialize - fuzzing unserialize() function
+* php-fuzz-json - fuzzing JSON parser
+* php-fuzz-exif - fuzzing exif_read_data() function (use --enable-exif)
+* php-fuzz-mbstring - fuzzing mb_ereg[i] (requires --enable-mbstring)
--- /dev/null
+AC_MSG_CHECKING(for clang fuzzer SAPI)
+
+PHP_ARG_ENABLE([fuzzer],,
+ [AS_HELP_STRING([--enable-fuzzer],
+ [Build PHP as clang fuzzing test module (for developers)])],
+ [no])
+
+dnl For newer clang versions see https://llvm.org/docs/LibFuzzer.html#fuzzer-usage
+dnl for relevant flags.
+
+dnl Macro to define fuzzing target
+dnl PHP_FUZZER_TARGET(name, target-var)
+dnl
+AC_DEFUN([PHP_FUZZER_TARGET], [
+ PHP_FUZZER_BINARIES="$PHP_FUZZER_BINARIES $SAPI_FUZZER_PATH/php-fuzz-$1"
+ PHP_SUBST($2)
+ PHP_ADD_SOURCES_X([sapi/fuzzer],[fuzzer-$1.c fuzzer-sapi.c],[],$2)
+])
+
+if test "$PHP_FUZZER" != "no"; then
+ AC_MSG_RESULT([yes])
+ PHP_REQUIRE_CXX()
+ PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/fuzzer/Makefile.frag)
+ SAPI_FUZZER_PATH=sapi/fuzzer
+ PHP_SUBST(SAPI_FUZZER_PATH)
+ if test -z "$LIB_FUZZING_ENGINE"; then
+ FUZZING_LIB="-lFuzzer"
+ FUZZING_CC="$CC"
+ AX_CHECK_COMPILE_FLAG([-fsanitize=address], [
+ CFLAGS="$CFLAGS -fsanitize=address"
+ CXXFLAGS="$CXXFLAGS -fsanitize=address"
+ LDFLAGS="$LDFLAGS -fsanitize=address"
+ ],[
+ AC_MSG_ERROR(compiler doesn't support -fsanitize flags)
+ ])
+ else
+ FUZZING_LIB="-lFuzzingEngine"
+ FUZZING_CC="$CXX -stdlib=libc++"
+ fi
+ PHP_SUBST(FUZZING_LIB)
+ PHP_SUBST(FUZZING_CC)
+
+ dnl PHP_SELECT_SAPI(fuzzer-parser, program, $FUZZER_SOURCES, , '$(SAPI_FUZZER_PATH)')
+
+ PHP_ADD_BUILD_DIR([sapi/fuzzer])
+ PHP_FUZZER_BINARIES=""
+ PHP_INSTALLED_SAPIS="$PHP_INSTALLED_SAPIS fuzzer"
+
+ PHP_FUZZER_TARGET([parser], PHP_FUZZER_PARSER_OBJS)
+ PHP_FUZZER_TARGET([unserialize], PHP_FUZZER_UNSERIALIZE_OBJS)
+ PHP_FUZZER_TARGET([exif], PHP_FUZZER_EXIF_OBJS)
+
+ if test -n "$enable_json" && test "$enable_json" != "no"; then
+ PHP_FUZZER_TARGET([json], PHP_FUZZER_JSON_OBJS)
+ fi
+ if test -n "$enable_mbstring" && test "$enable_mbstring" != "no"; then
+ PHP_FUZZER_TARGET([mbstring], PHP_FUZZER_MBSTRING_OBJS)
+ fi
+
+ PHP_SUBST(PHP_FUZZER_BINARIES)
+fi
+
+AC_MSG_RESULT($PHP_FUZZER)
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<html><head>
+<title>301 Moved Permanently</title>
+</head><body>
+<h1>Moved Permanently</h1>
+<p>The document has moved <a href="http://www.getid3.org/temp/62523.jpg">here</a>.</p>
+<hr>
+<address>Apache Server at getid3.org Port 80</address>
+</body></html>
--- /dev/null
+<html>\r
+ <head><title>Found</title></head>\r
+ <body>\r
+ <h1>Found</h1>\r
+ <p>The resource was found at <a href="http://dl.dropboxusercontent.com/u/7562584/Bugs/Php/bad_exif.jpeg">http://dl.dropboxusercontent.com/u/7562584/Bugs/Php/bad_exif.jpeg</a>;\r
+you should be redirected automatically.\r
+\r
+<!-- --></p>\r
+ <hr noshade>\r
+ <div align="right">WSGI Server</div>\r
+ </body>\r
+</html>\r
--- /dev/null
+{"prop":{"prop":null}}
--- /dev/null
+{"a":100.1,"b":"foo"}
--- /dev/null
+[100.1,"bar"]
--- /dev/null
+{"0":0,"\u0000ab":1,"1":"\u0000null-prefixed value"}
+
--- /dev/null
+{ "test": { "foo": "bar" } }
--- /dev/null
+"aa\udbff\udffdzz"
+
--- /dev/null
+"latin 1234 -\/ russian мама мыла раму specialchars \u0002 \b \n U+1D11E >𝄞<"
--- /dev/null
+{"test":"123343e871700"}
--- /dev/null
+[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
--- /dev/null
+{"myInt":99,"myFloat":123.45,"myNull":null,"myBool":true,"myString":"Hello World"}
--- /dev/null
+"\u65e5\u672c\u8a9e\u30c6\u30ad\u30b9\u30c8\u3067\u3059\u300201234\uff15\uff16\uff17\uff18\uff19\u3002"
--- /dev/null
+{"largenum":123456789012345678901234567890}
--- /dev/null
+["<foo>","'bar'","\"baz\"","&blong&"]
--- /dev/null
+["\u003Cfoo\u003E","\u0027bar\u0027","\u0022baz\u0022","\u0026blong\u0026"]
--- /dev/null
+[
+{"":"value"},
+{"":"value", "key":"value"},
+{"key":"value", "":"value"}
+]
--- /dev/null
+[123,13452345,123.13452345]
--- /dev/null
+["\ud834\udd00"]
+
--- /dev/null
+{"zero": 0e0}
--- /dev/null
+[null,null,"abc"]
--- /dev/null
+"A JSON payload should be an object or array, not a string."
\ No newline at end of file
--- /dev/null
+{"Extra value after close": true} "misplaced quoted value"
\ No newline at end of file
--- /dev/null
+{"Illegal expression": 1 + 2}
\ No newline at end of file
--- /dev/null
+{"Illegal invocation": alert()}
\ No newline at end of file
--- /dev/null
+{"Numbers cannot have leading zeroes": 013}
\ No newline at end of file
--- /dev/null
+{"Numbers cannot be hex": 0x14}
\ No newline at end of file
--- /dev/null
+["Illegal backslash escape: \x15"]
\ No newline at end of file
--- /dev/null
+[\naked]
\ No newline at end of file
--- /dev/null
+["Illegal backslash escape: \017"]
\ No newline at end of file
--- /dev/null
+[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
--- /dev/null
+{"Missing colon" null}
\ No newline at end of file
--- /dev/null
+["Unclosed array"
\ No newline at end of file
--- /dev/null
+{"Double colon":: null}
\ No newline at end of file
--- /dev/null
+{"Comma instead of colon", null}
\ No newline at end of file
--- /dev/null
+["Colon instead of comma": false]
\ No newline at end of file
--- /dev/null
+["Bad value", truth]
\ No newline at end of file
--- /dev/null
+['single quote']
\ No newline at end of file
--- /dev/null
+[" tab character in string "]
\ No newline at end of file
--- /dev/null
+["tab\ character\ in\ string\ "]
\ No newline at end of file
--- /dev/null
+["line
+break"]
\ No newline at end of file
--- /dev/null
+["line\
+break"]
\ No newline at end of file
--- /dev/null
+[0e]
\ No newline at end of file
--- /dev/null
+{unquoted_key: "keys must be quoted"}
\ No newline at end of file
--- /dev/null
+[0e+]
\ No newline at end of file
--- /dev/null
+[0e+-1]
\ No newline at end of file
--- /dev/null
+{"Comma instead if closing brace": true,
\ No newline at end of file
--- /dev/null
+["mismatch"}
\ No newline at end of file
--- /dev/null
+["extra comma",]
\ No newline at end of file
--- /dev/null
+["double extra comma",,]
\ No newline at end of file
--- /dev/null
+[ , "<-- missing value"]
\ No newline at end of file
--- /dev/null
+["Comma after the close"],
\ No newline at end of file
--- /dev/null
+["Extra close"]]
\ No newline at end of file
--- /dev/null
+{"Extra comma": true,}
\ No newline at end of file
--- /dev/null
+[
+ "JSON Test Pattern pass1",
+ {"object with 1 member":["array with 1 element"]},
+ {},
+ [],
+ -42,
+ true,
+ false,
+ null,
+ {
+ "integer": 1234567890,
+ "real": -9876.543210,
+ "e": 0.123456789e-12,
+ "E": 1.234567890E+34,
+ "": 23456789012E66,
+ "zero": 0,
+ "one": 1,
+ "space": " ",
+ "quote": "\"",
+ "backslash": "\\",
+ "controls": "\b\f\n\r\t",
+ "slash": "/ & \/",
+ "alpha": "abcdefghijklmnopqrstuvwyz",
+ "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
+ "digit": "0123456789",
+ "0123456789": "digit",
+ "special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
+ "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
+ "true": true,
+ "false": false,
+ "null": null,
+ "array":[ ],
+ "object":{ },
+ "address": "50 St. James Street",
+ "url": "http://www.JSON.org/",
+ "comment": "// /* <!-- --",
+ "# -- --> */": " ",
+ " s p a c e d " :[1,2 , 3
+
+,
+
+4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
+ "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
+ "quotes": "" \u0022 %22 0x22 034 "",
+ "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
+: "A key can be any string"
+ },
+ 0.5 ,98.6
+,
+99.44
+,
+
+1066,
+1e1,
+0.1e1,
+1e-1,
+1e00,2e+00,2e-00
+,"rosebud"]
\ No newline at end of file
--- /dev/null
+[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
--- /dev/null
+{
+ "JSON Test Pattern pass3": {
+ "The outermost value": "must be an object or array.",
+ "In this test": "It is an object."
+ }
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Stanislav Malyshev <stas@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "fuzzer.h"
+
+#include "Zend/zend.h"
+#include "main/php_config.h"
+#include "main/php_main.h"
+#include "ext/standard/php_var.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "fuzzer-sapi.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ char *filename;
+ int filedes;
+
+ if (php_request_startup()==FAILURE) {
+ php_module_shutdown();
+ return 0;
+ }
+
+ /* put the data in a file */
+ filename = tmpnam(NULL);
+ filedes = open(filename, O_CREAT|O_RDWR);
+ write(filedes, Data, Size);
+ close(filedes);
+
+ fuzzer_call_php_func("exif_read_data", 1, &filename);
+
+ /* cleanup */
+ unlink(filename);
+ php_request_shutdown(NULL);
+
+ return 0;
+}
+
+int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ fuzzer_init_php();
+
+ /* fuzzer_shutdown_php(); */
+ return 0;
+}
+
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Johannes Schlüter <johanes@php.net> |
+ | Stanislav Malyshev <stas@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+
+
+#include "fuzzer.h"
+
+#include "Zend/zend.h"
+#include "main/php_config.h"
+#include "main/php_main.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "fuzzer-sapi.h"
+
+#ifdef HAVE_JSON
+#include "ext/json/php_json_parser.h"
+#endif
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+#ifdef HAVE_JSON
+ char *data = malloc(Size+1);
+ memcpy(data, Data, Size);
+ data[Size] = '\0';
+
+ if (php_request_startup()==FAILURE) {
+ php_module_shutdown();
+ return 0;
+ }
+
+ for (int option = 0; option <=1; ++option) {
+ zval result;
+ php_json_parser parser;
+ php_json_parser_init(&parser, &result, data, Size, option, 10);
+ php_json_yyparse(&parser);
+
+ ZVAL_UNDEF(&result);
+ }
+
+ php_request_shutdown(NULL);
+
+ free(data);
+#else
+ fprintf(stderr, "\n\nERROR:\nPHP built without JSON, recompile with --enable-json to use this fuzzer\n");
+ exit(1);
+#endif
+ return 0;
+}
+
+int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ fuzzer_init_php();
+
+ /* fuzzer_shutdown_php(); */
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Stanislav Malyshev <stas@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+
+#include "fuzzer.h"
+
+#include "Zend/zend.h"
+#include "main/php_config.h"
+#include "main/php_main.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "fuzzer-sapi.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+#ifdef HAVE_MBREGEX
+ char *args[2];
+ char *data = malloc(Size+1);
+ memcpy(data, Data, Size);
+ data[Size] = '\0';
+
+ if (php_request_startup()==FAILURE) {
+ php_module_shutdown();
+ return 0;
+ }
+
+ args[0] = data;
+ args[1] = "test123";
+ fuzzer_call_php_func("mb_ereg", 2, args);
+
+ args[0] = data;
+ args[1] = "test123";
+ fuzzer_call_php_func("mb_eregi", 2, args);
+
+ args[0] = data;
+ args[1] = data;
+ fuzzer_call_php_func("mb_ereg", 2, args);
+
+ args[0] = data;
+ args[1] = data;
+ fuzzer_call_php_func("mb_eregi", 2, args);
+
+ php_request_shutdown(NULL);
+
+ free(data);
+#else
+ fprintf(stderr, "\n\nERROR:\nPHP built without mbstring, recompile with --enable-mbstring to use this fuzzer\n");
+ exit(1);
+#endif
+ return 0;
+}
+
+int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ fuzzer_init_php();
+
+ /* fuzzer_shutdown_php(); */
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Johannes Schlüter <johanes@php.net> |
+ | Stanislav Malyshev <stas@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include <main/php.h>
+#include <main/php_main.h>
+#include <main/SAPI.h>
+#include <ext/standard/info.h>
+#include <ext/standard/php_var.h>
+#include <main/php_variables.h>
+#ifdef JO0
+#include <ext/standard/php_smart_str.h>
+#endif
+
+#include "fuzzer.h"
+
+#include "fuzzer-sapi.h"
+
+int fuzzer_do_parse(zend_file_handle *file_handle, char *filename)
+{
+ int retval = FAILURE; /* failure by default */
+
+ SG(options) |= SAPI_OPTION_NO_CHDIR;
+ SG(request_info).argc=0;
+ SG(request_info).argv=NULL;
+
+ if (php_request_startup(TSRMLS_C)==FAILURE) {
+ php_module_shutdown(TSRMLS_C);
+ return FAILURE;
+ }
+
+ SG(headers_sent) = 1;
+ SG(request_info).no_headers = 1;
+ php_register_variable("PHP_SELF", filename, NULL TSRMLS_CC);
+
+ zend_first_try {
+ zend_compile_file(file_handle, ZEND_REQUIRE);
+ //retval = php_execute_script(file_handle TSRMLS_CC);
+ } zend_end_try();
+
+ php_request_shutdown((void *) 0);
+
+ return (retval == SUCCESS) ? SUCCESS : FAILURE;
+}
+
+int fuzzer_do_request_d(char *filename, char *data, size_t data_len);
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ char *s = malloc(Size+1);
+ memcpy(s, Data, Size);
+ s[Size] = '\0';
+
+ fuzzer_do_request_d("fuzzer.php", Data, Size);
+ //fuzzer_do_parse(&file_handle, "fuzzer.php");
+
+ free(s);
+ return 0;
+}
+
+int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ fuzzer_init_php();
+
+ /* fuzzer_shutdown_php(); */
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Johannes Schlüter <johanes@php.net> |
+ | Stanislav Malyshev <stas@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include <main/php.h>
+#include <main/php_main.h>
+#include <main/SAPI.h>
+#include <ext/standard/info.h>
+#include <ext/standard/php_var.h>
+#include <main/php_variables.h>
+
+#include "fuzzer.h"
+#include "fuzzer-sapi.h"
+
+const char HARDCODED_INI[] =
+ "html_errors=0\n"
+ "implicit_flush=1\n"
+ "max_execution_time=20\n"
+ "output_buffering=0\n";
+
+static int startup(sapi_module_struct *sapi_module)
+{
+ if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+static size_t ub_write(const char *str, size_t str_length TSRMLS_DC)
+{
+ /* quiet */
+ return str_length;
+}
+
+static void fuzzer_flush(void *server_context)
+{
+ /* quiet */
+}
+
+static void send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC)
+{
+}
+
+static char* read_cookies(TSRMLS_D)
+{
+ /* TODO: fuzz these! */
+ return NULL;
+}
+
+static void register_variables(zval *track_vars_array TSRMLS_DC)
+{
+ php_import_environment_variables(track_vars_array TSRMLS_CC);
+}
+
+static void log_message(char *message, int level TSRMLS_DC)
+{
+}
+
+
+static sapi_module_struct fuzzer_module = {
+ "fuzzer", /* name */
+ "clang fuzzer", /* pretty name */
+
+ startup, /* startup */
+ php_module_shutdown_wrapper, /* shutdown */
+
+ NULL, /* activate */
+ NULL, /* deactivate */
+
+ ub_write, /* unbuffered write */
+ fuzzer_flush, /* flush */
+ NULL, /* get uid */
+ NULL, /* getenv */
+
+ php_error, /* error handler */
+
+ NULL, /* header handler */
+ NULL, /* send headers handler */
+ send_header, /* send header handler */
+
+ NULL, /* read POST data */
+ read_cookies, /* read Cookies */
+
+ register_variables, /* register server variables */
+ log_message, /* Log message */
+ NULL, /* Get request time */
+ NULL, /* Child terminate */
+
+ STANDARD_SAPI_MODULE_PROPERTIES
+};
+
+int fuzzer_init_php()
+{
+ sapi_startup(&fuzzer_module);
+ fuzzer_module.phpinfo_as_text = 1;
+
+ fuzzer_module.ini_entries = malloc(sizeof(HARDCODED_INI));
+ memcpy(fuzzer_module.ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
+
+ /*
+ * TODO: we might want to test both Zend and malloc MM, but testing with malloc
+ * is more likely to find bugs, so use that for now.
+ */
+ putenv("USE_ZEND_ALLOC=0");
+
+#ifdef __SANITIZE_ADDRESS__
+ /* Not very interested in memory leak detection, since Zend MM does that */
+ __lsan_disable();
+#endif
+
+ if (fuzzer_module.startup(&fuzzer_module)==FAILURE) {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+void fuzzer_set_ini_file(const char *file)
+{
+ if (fuzzer_module.php_ini_path_override) {
+ free(fuzzer_module.php_ini_path_override);
+ }
+ fuzzer_module.php_ini_path_override = strdup(file);
+}
+
+
+int fuzzer_shutdown_php()
+{
+ TSRMLS_FETCH();
+
+ php_module_shutdown(TSRMLS_C);
+ sapi_shutdown();
+
+ free(fuzzer_module.ini_entries);
+ return SUCCESS;
+}
+
+int fuzzer_do_request(zend_file_handle *file_handle, char *filename)
+{
+ int retval = FAILURE; /* failure by default */
+
+ SG(options) |= SAPI_OPTION_NO_CHDIR;
+ SG(request_info).argc=0;
+ SG(request_info).argv=NULL;
+
+ if (php_request_startup(TSRMLS_C)==FAILURE) {
+ php_module_shutdown(TSRMLS_C);
+ return FAILURE;
+ }
+
+ SG(headers_sent) = 1;
+ SG(request_info).no_headers = 1;
+ php_register_variable("PHP_SELF", filename, NULL TSRMLS_CC);
+
+ zend_first_try {
+ zend_compile_file(file_handle, ZEND_REQUIRE);
+ /*retval = php_execute_script(file_handle TSRMLS_CC);*/
+ } zend_end_try();
+
+ php_request_shutdown((void *) 0);
+
+ return (retval == SUCCESS) ? SUCCESS : FAILURE;
+}
+
+
+int fuzzer_do_request_f(char *filename)
+{
+ zend_file_handle file_handle;
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.filename = filename;
+ file_handle.handle.fp = NULL;
+ file_handle.opened_path = NULL;
+
+ return fuzzer_do_request(&file_handle, filename);
+}
+
+int fuzzer_do_request_d(char *filename, char *data, size_t data_len)
+{
+ zend_file_handle file_handle;
+ file_handle.filename = filename;
+ file_handle.opened_path = NULL;
+ file_handle.handle.stream.handle = NULL;
+ file_handle.handle.stream.reader = (zend_stream_reader_t)_php_stream_read;
+ file_handle.handle.stream.fsizer = NULL;
+ file_handle.handle.stream.isatty = 0;
+ file_handle.handle.stream.closer = NULL;
+ file_handle.buf = data;
+ file_handle.len = data_len;
+ file_handle.type = ZEND_HANDLE_STREAM;
+
+ return fuzzer_do_request(&file_handle, filename);
+}
+
+// Call named PHP function with N zval arguments
+void fuzzer_call_php_func_zval(const char *func_name, int nargs, zval *args) {
+ zval retval, func;
+ int result;
+
+ ZVAL_STRING(&func, func_name);
+ ZVAL_UNDEF(&retval);
+ result = call_user_function(CG(function_table), NULL, &func, &retval, nargs, args);
+
+ // TODO: check result?
+ /* to ensure retval is not broken */
+ php_var_dump(&retval, 0);
+
+ /* cleanup */
+ zval_ptr_dtor(&retval);
+ zval_ptr_dtor(&func);
+}
+
+// Call named PHP function with N string arguments
+void fuzzer_call_php_func(const char *func_name, int nargs, char **params) {
+ zval args[nargs];
+ int i;
+
+ for(i=0;i<nargs;i++) {
+ ZVAL_STRING(&args[i], params[i]);
+ }
+
+ fuzzer_call_php_func_zval(func_name, nargs, args);
+
+ for(i=0;i<nargs;i++) {
+ zval_ptr_dtor(&args[i]);
+ ZVAL_UNDEF(&args[i]);
+ }
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Johannes Schlüter <johanes@php.net> |
+ | Stanislav Malyshev <stas@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+int fuzzer_init_php();
+void fuzzer_call_php_func(const char *func_name, int nargs, char **params);
+void fuzzer_call_php_func_zval(const char *func_name, int nargs, zval *args);
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Johannes Schlüter <johanes@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+
+#include "fuzzer.h"
+
+#include "Zend/zend.h"
+#include "main/php_config.h"
+#include "main/php_main.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "fuzzer-sapi.h"
+
+#include "ext/standard/php_var.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ unsigned char *data = malloc(Size+1);
+
+ memcpy(data, Data, Size);
+ data[Size] = '\0';
+
+ if (php_request_startup()==FAILURE) {
+ php_module_shutdown();
+ return 0;
+ }
+
+ zval result;
+
+ php_unserialize_data_t var_hash;
+ PHP_VAR_UNSERIALIZE_INIT(var_hash);
+ php_var_unserialize(&result, &data, data + Size, &var_hash);
+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+
+ zval_ptr_dtor(&result);
+
+ php_request_shutdown(NULL);
+
+ free(data);
+
+ return 0;
+}
+
+int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ fuzzer_init_php();
+
+ /* fuzzer_shutdown_php(); */
+ return 0;
+}
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Johannes Schlüter <johanes@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "php_version.h"
+#define FUZZER_VERSION PHP_VERSION
--- /dev/null
+#
+# AFL dictionary for JSON
+# -----------------------
+#
+# Just the very basics.
+#
+# Inspired by a dictionary by Jakub Wilk <jwilk@jwilk.net>
+#
+
+"0"
+",0"
+":0"
+"0:"
+"-1.2e+3"
+
+"true"
+"false"
+"null"
+
+"\"\""
+",\"\""
+":\"\""
+"\"\":"
+
+"{}"
+",{}"
+":{}"
+"{\"\":0}"
+"{{}}"
+
+"[]"
+",[]"
+":[]"
+"[0]"
+"[[]]"
+
+"''"
+"\\"
+"\\b"
+"\\f"
+"\\n"
+"\\r"
+"\\t"
+"\\u0000"
+"\\x00"
+"\\0"
+"\\uD800\\uDC00"
+"\\uDBFF\\uDFFF"
+
+"\"\":0"
+"//"
+"/**/"