mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge pull request #6812 from DavidKorczynski/oss-fuzz-ext
Add new fuzzing harness to be consumed by OSS-Fuzz
This commit is contained in:
@@ -103,3 +103,26 @@ snippet_multi=" 1*1"
|
||||
|
||||
string_single_q=" 'a'"
|
||||
string_dbl_q=" \"a\""
|
||||
regex_any="."
|
||||
regex_start="^"
|
||||
regex_end="$"
|
||||
regex_star="*"
|
||||
regex_plus="+"
|
||||
regex_maybe="?"
|
||||
regex_alt="|"
|
||||
regex_group_start="("
|
||||
regex_group_end=")"
|
||||
regex_class_start="["
|
||||
regex_class_end="]"
|
||||
regex_digit="\\d"
|
||||
regex_word="\\w"
|
||||
regex_space="\\s"
|
||||
regex_non_digit="\\D"
|
||||
regex_non_word="\\W"
|
||||
regex_non_space="\\S"
|
||||
regex_named="(?<name>)"
|
||||
regex_atomic="(?>)"
|
||||
regex_lookahead="(?=)"
|
||||
regex_neg_lookahead="(?!)"
|
||||
regex_lookbehind="(?<=)"
|
||||
regex_neg_lookbehind="(?<!)"
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mruby.h>
|
||||
#include <mruby/irep.h>
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t size) {
|
||||
if (size < 1) {
|
||||
return 0;
|
||||
}
|
||||
mrb_state *mrb = mrb_open();
|
||||
if (!mrb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* mrb_load_irep_buf returns the result of the last expression */
|
||||
mrb_load_irep_buf(mrb, Data, size);
|
||||
|
||||
mrb_close(mrb);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mruby.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/variable.h>
|
||||
#include <mruby/data.h>
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t size) {
|
||||
if (size < 2) {
|
||||
return 0;
|
||||
}
|
||||
mrb_state *mrb = mrb_open();
|
||||
if (!mrb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t selector = Data[0] % 4;
|
||||
const uint8_t *D = Data + 1;
|
||||
size_t S = size - 1;
|
||||
|
||||
if (selector == 0) {
|
||||
/* Target Set */
|
||||
struct RClass *set_class_ptr = mrb_class_get(mrb, "Set");
|
||||
if (set_class_ptr) {
|
||||
mrb_value set_class = mrb_obj_value(set_class_ptr);
|
||||
mrb_value ary = mrb_ary_new(mrb);
|
||||
for (size_t i = 0; i < S / 4 && i < 10; i++) {
|
||||
mrb_ary_push(mrb, ary, mrb_str_new(mrb, (const char *)(D + i*4), 4));
|
||||
}
|
||||
mrb_funcall(mrb, set_class, "new", 1, ary);
|
||||
}
|
||||
} else if (selector == 1) {
|
||||
/* Target Time */
|
||||
struct RClass *time_class_ptr = mrb_class_get(mrb, "Time");
|
||||
if (time_class_ptr) {
|
||||
mrb_value time_class = mrb_obj_value(time_class_ptr);
|
||||
if (S >= 8) {
|
||||
mrb_int sec = (mrb_int)D[0] | ((mrb_int)D[1] << 8) | ((mrb_int)D[2] << 16) | ((mrb_int)D[3] << 24);
|
||||
mrb_funcall(mrb, time_class, "at", 1, mrb_fixnum_value(sec));
|
||||
}
|
||||
mrb_funcall(mrb, time_class, "now", 0);
|
||||
}
|
||||
} else if (selector == 2) {
|
||||
/* Target Random */
|
||||
struct RClass *random_class_ptr = mrb_class_get(mrb, "Random");
|
||||
if (random_class_ptr) {
|
||||
mrb_value random_class = mrb_obj_value(random_class_ptr);
|
||||
if (S >= 4) {
|
||||
mrb_int seed = (mrb_int)D[0] | ((mrb_int)D[1] << 8);
|
||||
mrb_value rnd = mrb_funcall(mrb, random_class, "new", 1, mrb_fixnum_value(seed));
|
||||
mrb_funcall(mrb, rnd, "rand", 1, mrb_fixnum_value(100));
|
||||
}
|
||||
}
|
||||
} else if (selector == 3) {
|
||||
/* Target Range and Array-ext */
|
||||
if (S >= 4) {
|
||||
mrb_int start = (mrb_int)D[0];
|
||||
mrb_int end = (mrb_int)D[1];
|
||||
mrb_value range = mrb_funcall(mrb, mrb_obj_value(mrb->kernel_module), "Range", 2, mrb_fixnum_value(start), mrb_fixnum_value(end));
|
||||
mrb_funcall(mrb, range, "to_a", 0);
|
||||
}
|
||||
}
|
||||
|
||||
mrb_close(mrb);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mruby.h>
|
||||
#include <mruby/numeric.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/variable.h>
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t size) {
|
||||
if (size < 2) {
|
||||
return 0;
|
||||
}
|
||||
mrb_state *mrb = mrb_open();
|
||||
if (!mrb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t selector = Data[0] % 4;
|
||||
const uint8_t *D = Data + 1;
|
||||
size_t S = size - 1;
|
||||
|
||||
if (selector == 0) {
|
||||
/* Integer / BigInt */
|
||||
if (S < 3) goto done;
|
||||
uint8_t base = D[0] % 37;
|
||||
if (base < 2 && base != 0) base = 10;
|
||||
uint8_t op = D[1] % 5;
|
||||
uint16_t split = D[2]; // Simplified split
|
||||
if (S > 3) split = split % (S - 3);
|
||||
else split = 0;
|
||||
|
||||
mrb_value s1 = mrb_str_new(mrb, (const char *)(D + 3), split);
|
||||
mrb_value s2 = mrb_str_new(mrb, (const char *)(D + 3 + split), S - 3 - split);
|
||||
|
||||
mrb_value b1 = mrb_funcall(mrb, mrb_obj_value(mrb->kernel_module), "Integer", 2, s1, mrb_fixnum_value(base));
|
||||
mrb_value b2 = mrb_funcall(mrb, mrb_obj_value(mrb->kernel_module), "Integer", 2, s2, mrb_fixnum_value(base));
|
||||
|
||||
if (!mrb_nil_p(b1) && !mrb_nil_p(b2)) {
|
||||
switch (op) {
|
||||
case 0: mrb_funcall(mrb, b1, "+", 1, b2); break;
|
||||
case 1: mrb_funcall(mrb, b1, "-", 1, b2); break;
|
||||
case 2: mrb_funcall(mrb, b1, "*", 1, b2); break;
|
||||
case 3:
|
||||
if (mrb_test(mrb_funcall(mrb, b2, "!=", 1, mrb_fixnum_value(0)))) {
|
||||
mrb_funcall(mrb, b1, "/", 1, b2);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (mrb_test(mrb_funcall(mrb, b2, "<", 1, mrb_fixnum_value(1000)))) {
|
||||
mrb_funcall(mrb, b1, "**", 1, b2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (selector == 1) {
|
||||
/* Rational */
|
||||
if (S < 4) goto done;
|
||||
mrb_int n = (mrb_int)D[0] | ((mrb_int)D[1] << 8);
|
||||
mrb_int d = (mrb_int)D[2] | ((mrb_int)D[3] << 8);
|
||||
mrb_value r = mrb_funcall(mrb, mrb_obj_value(mrb->kernel_module), "Rational", 2, mrb_fixnum_value(n), mrb_fixnum_value(d));
|
||||
if (S >= 8) {
|
||||
mrb_int n2 = (mrb_int)D[4] | ((mrb_int)D[5] << 8);
|
||||
mrb_int d2 = (mrb_int)D[6] | ((mrb_int)D[7] << 8);
|
||||
mrb_value r2 = mrb_funcall(mrb, mrb_obj_value(mrb->kernel_module), "Rational", 2, mrb_fixnum_value(n2), mrb_fixnum_value(d2));
|
||||
mrb_funcall(mrb, r, "+", 1, r2);
|
||||
}
|
||||
} else if (selector == 2) {
|
||||
/* Complex */
|
||||
if (S < 4) goto done;
|
||||
mrb_float re = (mrb_float)D[0];
|
||||
mrb_float im = (mrb_float)D[1];
|
||||
struct RClass *complex_class = mrb_class_get(mrb, "Complex");
|
||||
if (complex_class) {
|
||||
mrb_value c = mrb_funcall(mrb, mrb_obj_value(mrb->kernel_module), "Complex", 2, mrb_float_value(mrb, re), mrb_float_value(mrb, im));
|
||||
mrb_funcall(mrb, c, "abs", 0);
|
||||
}
|
||||
} else if (selector == 3) {
|
||||
/* Math functions */
|
||||
if (S < 8) goto done;
|
||||
double d1;
|
||||
memcpy(&d1, D, sizeof(double));
|
||||
struct RClass *math_module = mrb_module_get(mrb, "Math");
|
||||
if (math_module) {
|
||||
mrb_value m = mrb_obj_value(math_module);
|
||||
mrb_funcall(mrb, m, "sin", 1, mrb_float_value(mrb, d1));
|
||||
mrb_funcall(mrb, m, "log", 1, mrb_float_value(mrb, d1));
|
||||
mrb_funcall(mrb, m, "sqrt", 1, mrb_float_value(mrb, d1));
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
mrb_close(mrb);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mruby.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/string.h>
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t size) {
|
||||
if (size < 2) {
|
||||
return 0;
|
||||
}
|
||||
mrb_state *mrb = mrb_open();
|
||||
if (!mrb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t fmt_len = Data[0];
|
||||
if (fmt_len > size - 1) {
|
||||
fmt_len = size - 1;
|
||||
}
|
||||
|
||||
mrb_value fmt = mrb_str_new(mrb, (const char *)(Data + 1), fmt_len);
|
||||
mrb_value str = mrb_str_new(mrb, (const char *)(Data + 1 + fmt_len), size - 1 - fmt_len);
|
||||
|
||||
/* Target String#unpack */
|
||||
mrb_funcall(mrb, str, "unpack", 1, fmt);
|
||||
|
||||
/* Target Array#pack (using the result of unpack if it's an array) */
|
||||
/* Or just pack the original string as an array of bytes */
|
||||
mrb_value ary = mrb_ary_new_capa(mrb, size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
mrb_ary_push(mrb, ary, mrb_fixnum_value(Data[i]));
|
||||
}
|
||||
mrb_funcall(mrb, ary, "pack", 1, fmt);
|
||||
|
||||
mrb_close(mrb);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mruby.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/variable.h>
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t size) {
|
||||
if (size < 3) {
|
||||
return 0;
|
||||
}
|
||||
mrb_state *mrb = mrb_open();
|
||||
if (!mrb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use first byte for flags */
|
||||
uint8_t flags_byte = Data[0];
|
||||
mrb_value flags = mrb_fixnum_value(flags_byte & 0x07); // i, m, x flags
|
||||
|
||||
/* Split remaining data into pattern and string */
|
||||
uint8_t pattern_len = Data[1];
|
||||
if (pattern_len > size - 2) {
|
||||
pattern_len = size - 2;
|
||||
}
|
||||
|
||||
mrb_value pattern = mrb_str_new(mrb, (const char *)(Data + 2), pattern_len);
|
||||
mrb_value text = mrb_str_new(mrb, (const char *)(Data + 2 + pattern_len), size - 2 - pattern_len);
|
||||
|
||||
/* Target Regexp.new(pattern, flags) */
|
||||
struct RClass *regexp_class_ptr = mrb_class_get(mrb, "Regexp");
|
||||
if (regexp_class_ptr) {
|
||||
mrb_value regexp_class = mrb_obj_value(regexp_class_ptr);
|
||||
mrb_value regexp = mrb_funcall(mrb, regexp_class, "new", 2, pattern, flags);
|
||||
|
||||
/* Target Regexp#match(text) */
|
||||
if (!mrb_nil_p(regexp)) {
|
||||
mrb_funcall(mrb, regexp, "match", 1, text);
|
||||
}
|
||||
}
|
||||
|
||||
mrb_close(mrb);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <mruby.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/array.h>
|
||||
#include <mruby/variable.h>
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t size) {
|
||||
if (size < 1) {
|
||||
return 0;
|
||||
}
|
||||
mrb_state *mrb = mrb_open();
|
||||
if (!mrb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use the first byte as a format string length */
|
||||
uint8_t fmt_len = Data[0];
|
||||
if (fmt_len > size - 1) {
|
||||
fmt_len = size - 1;
|
||||
}
|
||||
|
||||
mrb_value fmt = mrb_str_new(mrb, (const char *)(Data + 1), fmt_len);
|
||||
|
||||
/* provide some arguments of different types to satisfy various format specifiers */
|
||||
mrb_value args[5];
|
||||
args[0] = mrb_fixnum_value(123);
|
||||
args[1] = mrb_float_value(mrb, 3.14);
|
||||
args[2] = mrb_str_new_cstr(mrb, "fuzz");
|
||||
args[3] = mrb_symbol_value(mrb_intern_cstr(mrb, "symbol"));
|
||||
args[4] = mrb_ary_new(mrb);
|
||||
|
||||
/* Call sprintf via mrb_funcall */
|
||||
/* We don't use all args every time, but it doesn't hurt to pass them */
|
||||
mrb_funcall(mrb, mrb_obj_value(mrb->kernel_module), "sprintf", 6, fmt, args[0], args[1], args[2], args[3], args[4]);
|
||||
|
||||
mrb_close(mrb);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user