Add quiet regex test mode for inclusion in pihole -q

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2020-06-28 22:25:37 +02:00
parent dde020ea54
commit c02dfddebc
4 changed files with 70 additions and 35 deletions
+12 -4
View File
@@ -32,6 +32,7 @@ static inline bool strEndsWith(const char *input, const char *end){
void parse_args(int argc, char* argv[])
{
bool quiet = false;
// Regardless of any arguments, we always pass "-k" (nofork) to dnsmasq
argc_dnsmasq = 2;
argv_dnsmasq = calloc(argc_dnsmasq, sizeof(char*));
@@ -155,15 +156,22 @@ void parse_args(int argc, char* argv[])
ok = true;
}
// Quiet mode
if(strcmp(argv[i], "-q") == 0)
{
quiet = true;
ok = true;
}
// Regex test mode
if(strcmp(argv[i], "regex-test") == 0)
{
// Enable stdout printing
cli_mode = true;
if(argc == i + 2)
exit(regex_test(debug, argv[i + 1], NULL));
exit(regex_test(debug, quiet, argv[i + 1], NULL));
else if(argc == i + 3)
exit(regex_test(debug, argv[i + 1], argv[i + 2]));
exit(regex_test(debug, quiet, argv[i + 1], argv[i + 2]));
else
{
printf("pihole-FTL: invalid option -- '%s' need either one or two parameters\nTry '%s --help' for more information\n", argv[i], argv[0]);
@@ -257,10 +265,10 @@ const char __attribute__ ((const)) *cli_cross(void)
return is_term() ? "["COL_RED""COL_NC"]" : "[✗]";
}
// Returns [!]
// Returns [i]
const char __attribute__ ((const)) *cli_info(void)
{
return "[i]";
return is_term() ? COL_BOLD"[i]"COL_NC : "[i]";
}
// Returns [?]
+50 -7
View File
@@ -139,20 +139,20 @@ int match_regex(const char *input, const int clientID, const enum regex_type reg
if(regextest && regexid == REGEX_CLI)
{
// CLI provided regular expression
logg(" %s%s%s matches",
logg(" %s%s%s matches",
cli_bold(), regexbuffer[regexid][index], cli_normal());
}
else if(regextest && regexid == REGEX_BLACKLIST)
{
// Database-sourced regular expression
logg(" %s%s%s matches (regex blacklist, DB ID %i)",
logg(" %s%s%s matches (regex blacklist, DB ID %i)",
cli_bold(), regexbuffer[regexid][index], cli_normal(),
regex_id[regexid][index]);
}
else if(regextest && regexid == REGEX_WHITELIST)
{
// Database-sourced regular expression
logg(" %s%s%s matches (regex whitelist, DB ID %i)",
logg(" %s%s%s matches (regex whitelist, DB ID %i)",
cli_bold(), regexbuffer[regexid][index], cli_normal(),
regex_id[regexid][index]);
}
@@ -351,7 +351,7 @@ void read_regex_from_database(void)
counters->clients, timer_elapsed_msec(REGEX_TIMER));
}
int regex_test(const bool debug_mode, const char *domainin, const char *regexin)
int regex_test(const bool debug_mode, const bool quiet, const char *domainin, const char *regexin)
{
// Prepare counters and regex memories
counters = calloc(1, sizeof(countersStruct));
@@ -370,19 +370,48 @@ int regex_test(const bool debug_mode, const char *domainin, const char *regexin)
if(regexin == NULL)
{
// Read and compile regex lists from database
if(!quiet)
{
logg("%s Loading regex filters from database...", cli_info());
timer_start(REGEX_TIMER);
}
read_regex_table(REGEX_BLACKLIST);
read_regex_table(REGEX_WHITELIST);
if(!quiet)
{
logg(" Compiled %i black- and %i whitelist regex filters in %.3f msec\n",
counters->num_regex[REGEX_BLACKLIST],
counters->num_regex[REGEX_WHITELIST],
timer_elapsed_msec(REGEX_TIMER));
}
// Check user-provided domain against all loaded regular blacklist expressions
matchidx = match_regex(domainin, -1, REGEX_BLACKLIST, true);
if(!quiet)
{
logg("%s Checking domain against blacklist...", cli_info());
timer_start(REGEX_TIMER);
}
int matchidx1 = match_regex(domainin, -1, REGEX_BLACKLIST, true);
if(!quiet)
logg(" Time: %.3f msec", timer_elapsed_msec(REGEX_TIMER));
// Check user-provided domain against all loaded regular whitelist expressions
matchidx = match_regex(domainin, -1, REGEX_WHITELIST, true);
if(!quiet)
{
logg("%s Checking domain against whitelist...", cli_info());
timer_start(REGEX_TIMER);
}
int matchidx2 = match_regex(domainin, -1, REGEX_WHITELIST, true);
if(!quiet)
logg(" Time: %.3f msec", timer_elapsed_msec(REGEX_TIMER));
matchidx = MAX(matchidx1, matchidx2);
}
else
{
// Compile CLI regex
if(!quiet)
logg("%s Compiling regex filter...", cli_info());
counters->num_regex[REGEX_BLACKLIST] = counters->num_regex[REGEX_WHITELIST] = 0;
counters->num_regex[REGEX_CLI] = 1;
@@ -393,14 +422,28 @@ int regex_test(const bool debug_mode, const char *domainin, const char *regexin)
regexbuffer[REGEX_CLI] = calloc(counters->num_regex[REGEX_CLI], sizeof(char*));
// Compile CLI regex
timer_start(REGEX_TIMER);
if(!quiet)
timer_start(REGEX_TIMER);
if(compile_regex(regexin, 0, REGEX_CLI, -1))
regex_available[REGEX_CLI][0] = true;
else
return EXIT_FAILURE;
if(!quiet)
logg(" Compiled regex filter in %.3f msec\n", timer_elapsed_msec(REGEX_TIMER));
// Check user-provided domain against user-provided regular expression
if(!quiet)
{
logg("Checking domain...");
timer_start(REGEX_TIMER);
}
matchidx = match_regex(domainin, -1, REGEX_CLI, true);
if(!quiet)
{
if(matchidx == -1)
logg(" NO MATCH!");
logg(" Time: %.3f msec", timer_elapsed_msec(REGEX_TIMER));
}
}
// Return status 0 = MATCH, 1 = ERROR, 2 = NO MATCH
+1 -1
View File
@@ -19,6 +19,6 @@ int match_regex(const char *input, const int clientID, const enum regex_type, co
void allocate_regex_client_enabled(clientsData *client, const int clientID);
void read_regex_from_database(void);
int regex_test(const bool debug_mode, const char *domainin, const char *regexin);
int regex_test(const bool debug_mode, const bool quiet, const char *domainin, const char *regexin);
#endif //REGEX_H
+7 -23
View File
@@ -404,161 +404,138 @@
@test "Regex Test 1: \"regex7.test.pi-hole.net\" vs. [database regex]: MATCH" {
run bash -c './pihole-FTL regex-test "regex7.test.pi-hole.net"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 2: \"a\" vs. \"a\": MATCH" {
run bash -c './pihole-FTL regex-test "a" "a"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 3: \"aa\" vs. \"^[a-z]{1,3}$\": MATCH" {
run bash -c './pihole-FTL regex-test "aa" "^[a-z]{1,3}$"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 4: \"aaaa\" vs. \"^[a-z]{1,3}$\": NO MATCH" {
run bash -c './pihole-FTL regex-test "aaaa" "^[a-z]{1,3}$"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✗]"* ]]
[[ $status == 2 ]]
}
@test "Regex Test 5: \"aa\" vs. \"^a(?#some comment)a$\": MATCH (comments)" {
run bash -c './pihole-FTL regex-test "aa" "^a(?#some comment)a$"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 6: \"abc.abc\" vs. \"([a-z]*)\.\1\": MATCH" {
run bash -c './pihole-FTL regex-test "abc.abc" "([a-z]*)\.\1"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 7: Complex character set: MATCH" {
run bash -c './pihole-FTL regex-test "__abc#LMN012$x%yz789*" "[[:digit:]a-z#$%]+"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 8: Range expression: MATCH" {
run bash -c './pihole-FTL regex-test "!ABC-./XYZ~" "[--Z]+"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 9: Back reference: \"aabc\" vs. \"(a)\1{1,2}\": MATCH" {
run bash -c './pihole-FTL regex-test "aabc" "(a)\1{1,2}"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 10: Back reference: \"foo\" vs. \"(.)\1$\": MATCH" {
run bash -c './pihole-FTL regex-test "foo" "(.)\1$"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 11: Back reference: \"foox\" vs. \"(.)\1$\": NO MATCH" {
run bash -c './pihole-FTL regex-test "foox" "(.)\1$"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✗]"* ]]
[[ $status == 2 ]]
}
@test "Regex Test 12: Back reference: \"1234512345\" vs. \"([0-9]{5})\1\": MATCH" {
run bash -c './pihole-FTL regex-test "1234512345" "([0-9]{5})\1"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 13: Back reference: \"12345\" vs. \"([0-9]{5})\1\": NO MATCH" {
run bash -c './pihole-FTL regex-test "12345" "([0-9]{5})\1"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✗]"* ]]
[[ $status == 2 ]]
}
@test "Regex Test 14: Complex back reference: MATCH" {
run bash -c './pihole-FTL regex-test "cat.foo.dog---cat%dog!foo" "(cat)\.(foo)\.(dog)---\1%\3!\2"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 15: Approximate matching, 0 errors: MATCH" {
run bash -c './pihole-FTL regex-test "foobarzap" "foo(bar){~1}zap"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 16: Approximate matching, 1 error (inside fault-tolerant area): MATCH" {
run bash -c './pihole-FTL regex-test "foobrzap" "foo(bar){~1}zap"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 17: Approximate matching, 1 error (outside fault-tolert area): NO MATCH" {
run bash -c './pihole-FTL regex-test "foxbrazap" "foo(bar){~1}zap"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✗]"* ]]
[[ $status == 2 ]]
}
@test "Regex Test 18: Approximate matching, 0 global errors: MATCH" {
run bash -c './pihole-FTL regex-test "foobar" "^(foobar){~1}$"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 19: Approximate matching, 1 global error: MATCH" {
run bash -c './pihole-FTL regex-test "cfoobar" "^(foobar){~1}$"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 20: Approximate matching, 2 global errors: NO MATCH" {
run bash -c './pihole-FTL regex-test "ccfoobar" "^(foobar){~1}$"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✗]"* ]]
[[ $status == 2 ]]
}
@test "Regex Test 21: Approximate matching, insert + substitute: MATCH" {
run bash -c './pihole-FTL regex-test "oobargoobaploowap" "(foobar){+2#2~2}"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 22: Approximate matching, insert + delete: MATCH" {
run bash -c './pihole-FTL regex-test "3oifaowefbaoraofuiebofasebfaobfaorfeoaro" "(foobar){+1 -2}"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✓]"* ]]
[[ $status == 0 ]]
}
@test "Regex Test 23: Approximate matching, insert + delete (insufficient): NO MATCH" {
run bash -c './pihole-FTL regex-test "3oifaowefbaoraofuiebofasebfaobfaorfeoaro" "(foobar){+1 -1}"'
printf "%s\n" "${lines[@]}"
[[ ${lines[4]} == "[✗]"* ]]
[[ $status == 2 ]]
}
@@ -632,6 +609,13 @@
[[ $status == 1 ]]
}
@test "Regex Test 34: Quiet mode gives only one line as result" {
run bash -c './pihole-FTL -q regex-test "fbcdn.net" "f"'
printf "%s\n" "${lines[@]}"
[[ ${lines[0]} == " f matches" ]]
[[ $status == 0 ]]
}
# x86_64-musl is built on busybox which has a slightly different
# variant of ls displaying three, instead of one, spaces between the
# user and group names.