fuzzer/c2: add roundtrip test

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-02-17 01:52:07 +00:00
parent 1159a8ae1a
commit ae43154470
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
3 changed files with 40 additions and 4 deletions

View File

@ -1521,6 +1521,10 @@ static const char *c2_condition_to_str2(const c2_ptr_t ptr) {
return buf;
}
const char *c2_lptr_to_str(const c2_lptr_t *ptr) {
return c2_condition_to_str2(ptr->ptr);
}
static inline bool c2_int_op(const c2_l_t *leaf, size_t ntargets, const int64_t *targets) {
for (size_t i = 0; i < ntargets; ++i) {
long long tgt = targets[i];

View File

@ -29,6 +29,7 @@ struct managed_win;
typedef void (*c2_userdata_free)(void *);
c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data);
const char *c2_lptr_to_str(const c2_lptr_t *ptr);
c2_lptr_t *c2_free_lptr(c2_lptr_t *lp, c2_userdata_free f);

View File

@ -2,6 +2,7 @@
#include "c2.h"
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include "config.h"
#include "log.h"
@ -14,7 +15,37 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
return 0;
}
c2_lptr_t *cond = c2_parse(NULL, (char *)data, NULL);
(void)cond;
(void)size;
return 0; // Values other than 0 and -1 are reserved for future use.
}
if (!cond) {
return 0;
}
// If we can parse it, we check if it roundtrips.
// Except when the input or the stringified condition has ':' at the second
// position, because that becomes a "legacy" pattern and is parsed differently.
char *str = strdup(c2_lptr_to_str(cond));
c2_free_lptr(cond, NULL);
if (str[1] == ':') {
free(str);
return 0;
}
c2_lptr_t *cond2 = c2_parse(NULL, str, NULL);
// The stringified condition could legitimately fail to parse, for example,
// "a=1 || b=2 || c=3 || ... ", when stringified, will be "((((((a=1 || b=2) ||
// c=3) || ...)", which will fail to parse because of the parenthese nest level
// limit.
if (cond2 == NULL) {
free(str);
return 0;
}
const char *str2 = c2_lptr_to_str(cond2);
c2_free_lptr(cond2, NULL);
if (strcmp(str, str2) != 0) {
fprintf(stderr, "Mismatch: %s != %s\n", str, str2);
abort();
}
free(str);
return 0;
}