rizin/test/unit/test_regex.c
Florian Märkl d9950f7479
Replace bp/sp-vars by generic stack-based ones (#3167)
Variables on the stack are not identified by bp/sp+<offset> anymore, but
by their address from the bottom of the stack frame (RzStackAddr),
independent of how they are accessed.
So now there are only two kinds of variables: stack and register.

This required some major refactoring and other changes:
* RzAnalysisVar.isarg was removed. Whether a variable is an argument is
  now specified implicitly by its storage location.
* Varsub of struct fields had to be rewritten so fields can be queried
  by arbitrary stack addresses using the recently introduced sp
  tracking, as the old approach to fill a list with all fields would not
  work anymore.
* analysis.vars.stackname was removed, new behavior is more similar to
  this being true before.
* Variables will not be created at stack+0 now, because the return
  address is there. Before, vars were only created sometimes in such
  cases.
* Variables created from bp offsets in x86 are not deleted anymore if
  the function's bp_frame is false (see removed
  rz_analysis_function_delete_vars_by_kind(fcn,
  RZ_ANALYSIS_VAR_KIND_BPV); calls). This may lead to some
  false-positive detected variables. Whether this really is a practical
  issue is yet to be seen. At least there are no meaningful tests that
  are broken by this.
* Applying variables from dwarf needed some fixes for determining the
  correct stack locations of variables in order to write meaningful
  tests. The handling is still not entirely correct for all
  possibilities of dwarf info, but at least the changed/added test cases
  are right and serve as a reference for future changes.
* Projects version 11 is introduced.
* afvb commands have been removed, afvs now handles all stack vars.
2023-01-02 11:36:21 +08:00

90 lines
3.7 KiB
C

// SPDX-FileCopyrightText: 2022 Florian Märkl <info@florianmaerkl.de>
// SPDX-FileCopyrightText: 2022 GustavoLCR <gugulcr@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_regex.h>
#include "minunit.h"
bool exec_regex(RzRegex *regex, const char *str, RzRegexMatch *out) {
RzRegexMatch match[2];
mu_assert_true(rz_regex_exec(regex, str, 1, &match[0], 0) == 0, "Regex match failed");
mu_assert_true(rz_regex_exec(regex, str, 1, &match[1], RZ_REGEX_LARGE) == 0, "Regex match failed for large engine");
mu_assert_memeq((ut8 *)&match[0], (ut8 *)&match[1], sizeof(RzRegexMatch), "Results from large engine match does not equal small engine match");
*out = match[0];
return true;
}
bool test_rz_reg_exec(void) {
const char *p = "abc|123";
RzRegex *reg = rz_regex_new(p, "e");
mu_assert_notnull(reg, "Regex was NULL");
RzRegexMatch match;
mu_assert_true(exec_regex(reg, "abc", &match), "Regex match failed");
mu_assert_eq(match.rm_so, 0, "Start of match is not 0");
mu_assert_eq(match.rm_eo, 3, "Start of match is not 3");
mu_assert_true(exec_regex(reg, "zabc", &match), "Regex match failed");
mu_assert_eq(match.rm_so, 1, "Start of match is not 1");
mu_assert_eq(match.rm_eo, 4, "Start of match is not 4");
mu_assert_true(exec_regex(reg, "abcz", &match), "Regex match failed");
mu_assert_eq(match.rm_so, 0, "Start of match is not 0");
mu_assert_eq(match.rm_eo, 3, "Start of match is not 3");
mu_assert_true(exec_regex(reg, "123", &match), "Regex match failed");
mu_assert_eq(match.rm_so, 0, "Start of match is not 0");
mu_assert_eq(match.rm_eo, 3, "Start of match is not 3");
mu_assert_true(exec_regex(reg, "z123", &match), "Regex match failed");
mu_assert_eq(match.rm_so, 1, "Start of match is not 1");
mu_assert_eq(match.rm_eo, 4, "Start of match is not 4");
mu_assert_true(exec_regex(reg, "123z", &match), "Regex match failed");
mu_assert_eq(match.rm_so, 0, "Start of match is not 0");
mu_assert_eq(match.rm_eo, 3, "Start of match is not 3");
rz_regex_free(reg);
const char *p_big = "\\d+(([abc]*d[efg])+|[123]4[567]+)*|[zyx]+(test)+[mnb]";
reg = rz_regex_new(p_big, "e");
mu_assert_true(exec_regex(reg, "z1abcde123z", &match), "Regex match failed");
mu_assert_eq(match.rm_so, 1, "Start of match is not 1");
mu_assert_eq(match.rm_eo, 7, "Start of match is not 7");
mu_assert_true(exec_regex(reg, "ayztesttestb123z", &match), "Regex match failed");
mu_assert_eq(match.rm_so, 1, "Start of match is not 1");
mu_assert_eq(match.rm_eo, 12, "Start of match is not 11");
rz_regex_free(reg);
mu_end;
}
bool test_rz_regex_capture(void) {
char *str = "abcd PrefixHello42s xyz";
RzRegex *re = rz_regex_new("[a-zA-Z]*(H[a-z]+)([0-9]*)s", "e");
mu_assert_notnull(re, "regex_new");
RzRegexMatch groups[4];
int r = rz_regex_exec(re, str, RZ_ARRAY_SIZE(groups), groups, 0);
mu_assert_eq(r, 0, "regex_exec");
mu_assert_eq(groups[0].rm_so, 5, "full match start");
mu_assert_eq(groups[0].rm_eo, 19, "full match end");
char *s = rz_regex_match_extract(str, &groups[0]);
mu_assert_streq_free(s, "PrefixHello42s", "full match extract");
mu_assert_eq(groups[1].rm_so, 11, "capture 1 start");
mu_assert_eq(groups[1].rm_eo, 16, "capture 1 end");
s = rz_regex_match_extract(str, &groups[1]);
mu_assert_streq_free(s, "Hello", "capture 1 extract");
mu_assert_eq(groups[2].rm_so, 16, "capture 2 start");
mu_assert_eq(groups[2].rm_eo, 18, "capture 2 end");
s = rz_regex_match_extract(str, &groups[2]);
mu_assert_streq_free(s, "42", "capture 2 extract");
mu_assert_eq(groups[3].rm_so, -1, "capture 3 start");
mu_assert_eq(groups[3].rm_eo, -1, "capture 3 end");
s = rz_regex_match_extract(str, &groups[3]);
mu_assert_null(s, "capture 3 extract");
rz_regex_free(re);
mu_end;
}
int main() {
mu_run_test(test_rz_reg_exec);
mu_run_test(test_rz_regex_capture);
}