diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/ipaddrcheck_functions.c | 61 | ||||
-rw-r--r-- | src/ipaddrcheck_functions.h | 4 | ||||
-rw-r--r-- | src/ipaddrcheck_functions.o | bin | 55552 -> 0 bytes |
4 files changed, 44 insertions, 27 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 1c43bae..ce8ea59 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ -AM_CFLAGS = --pedantic -Wall -Werror -Wno-error=format-overflow= -std=c99 -O2 -AM_LDFLAGS = +AM_CFLAGS = --pedantic -Wall -Werror -std=c99 -O2 +AM_CPPFLAGS = $(PCRE2_CFLAGS) ipaddrcheck_SOURCES = ipaddrcheck.c ipaddrcheck_functions.c -ipaddrcheck_LDADD = -lcidr -lpcre +ipaddrcheck_LDADD = -lcidr $(PCRE2_LIBS) bin_PROGRAMS = ipaddrcheck diff --git a/src/ipaddrcheck_functions.c b/src/ipaddrcheck_functions.c index 2d2dff3..fb0e654 100644 --- a/src/ipaddrcheck_functions.c +++ b/src/ipaddrcheck_functions.c @@ -41,25 +41,31 @@ int regex_matches(const char* regex, const char* str) { - int offsets[1]; - pcre *re; + pcre2_code *re; int rc; - const char *error; - int erroffset; + int out; + int error; + PCRE2_SIZE erroffset; - re = pcre_compile(regex, 0, &error, &erroffset, NULL); + re = pcre2_compile((PCRE2_SPTR)regex, PCRE2_ZERO_TERMINATED, 0, &error, &erroffset, NULL); assert(re != NULL); - rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, offsets, 1); + pcre2_match_data *match = pcre2_match_data_create_from_pattern(re, NULL); + + rc = pcre2_match(re, (PCRE2_SPTR)str, strlen(str), 0, 0, match, NULL); if( rc >= 0) { - return RESULT_SUCCESS; + out = RESULT_SUCCESS; } else { - return RESULT_FAILURE; + out = RESULT_FAILURE; } + + pcre2_match_data_free(match); + pcre2_code_free(re); + return out; } @@ -546,7 +552,10 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) If the regex check succeeded, we know the hyphen is there. */ split_range(range_str, left, right); - if( !is_ipv4_single(left) ) + CIDR* left_addr = cidr_from_str(left); + CIDR* right_addr = cidr_from_str(right); + + if( !(is_ipv4_single(left) && is_valid_address(left_addr)) ) { if( verbose ) { @@ -554,7 +563,7 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - else if( !is_ipv4_single(right) ) + else if( !(is_ipv4_single(right) && is_valid_address(right_addr)) ) { if( verbose ) { @@ -564,8 +573,6 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) } else { - CIDR* left_addr = cidr_from_str(left); - CIDR* right_addr = cidr_from_str(right); struct in_addr* left_in_addr = cidr_to_inaddr(left_addr, NULL); struct in_addr* right_in_addr = cidr_to_inaddr(right_addr, NULL); @@ -577,10 +584,13 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) { char left_pref_str[19]; - /* XXX: Prefix length size is checked elsewhere, so it can't be more than 2 characters (32) + /* XXX: Prefix length size is checked elsewhere with a regex, so it can't be more than 2 characters (32) and overflow cannot occur. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-overflow=" sprintf(left_pref_str, "%s/%u", left, prefix_length); + #pragma GCC diagnostic pop CIDR* left_addr_with_pref = cidr_from_str(left_pref_str); CIDR* left_net = cidr_addr_network(left_addr_with_pref); if( cidr_contains(left_net, right_addr) == 0 ) @@ -608,9 +618,9 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) result = RESULT_FAILURE; } - cidr_free(left_addr); - cidr_free(right_addr); } + cidr_free(left_addr); + cidr_free(right_addr); } return(result); @@ -644,7 +654,11 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) If the regex check succeeded, we know the hyphen is there. */ split_range(range_str, left, right); - if( !is_ipv6_single(left) ) + CIDR* left_addr = cidr_from_str(left); + CIDR* right_addr = cidr_from_str(right); + + if( !(is_ipv6_single(left) && + is_valid_address(left_addr) && !duplicate_double_colons(left)) ) { if( verbose ) { @@ -652,7 +666,8 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - else if( !is_ipv6_single(right) ) + else if( !(is_ipv6_single(right) && + is_valid_address(right_addr) && !duplicate_double_colons(right)) ) { if( verbose ) { @@ -662,8 +677,6 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } else { - CIDR* left_addr = cidr_from_str(left); - CIDR* right_addr = cidr_from_str(right); struct in6_addr* left_in6_addr = cidr_to_in6addr(left_addr, NULL); struct in6_addr* right_in6_addr = cidr_to_in6addr(right_addr, NULL); @@ -675,10 +688,13 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) { char left_pref_str[44]; - /* XXX: Prefix length size is checked elsewhere, so it can't be more than 3 characters (128) + /* XXX: Prefix length size is checked elsewhere with a regex, so it can't be more than 3 characters (128) and overflow cannot occur. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-overflow=" sprintf(left_pref_str, "%s/%u", left, prefix_length); + #pragma GCC diagnostic pop CIDR* left_addr_with_pref = cidr_from_str(left_pref_str); CIDR* left_net = cidr_addr_network(left_addr_with_pref); if( cidr_contains(left_net, right_addr) == 0 ) @@ -705,10 +721,9 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - - cidr_free(left_addr); - cidr_free(right_addr); } + cidr_free(left_addr); + cidr_free(right_addr); } return(result); diff --git a/src/ipaddrcheck_functions.h b/src/ipaddrcheck_functions.h index 9b5e55f..b717d74 100644 --- a/src/ipaddrcheck_functions.h +++ b/src/ipaddrcheck_functions.h @@ -23,11 +23,13 @@ #ifndef IPADDRCHECK_FUNCTIONS_H #define IPADDRCHECK_FUNCTIONS_H +#define PCRE2_CODE_UNIT_WIDTH 8 + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <getopt.h> -#include <pcre.h> +#include <pcre2.h> #include <libcidr.h> #define INVALID_PROTO -1 diff --git a/src/ipaddrcheck_functions.o b/src/ipaddrcheck_functions.o Binary files differdeleted file mode 100644 index a689dac..0000000 --- a/src/ipaddrcheck_functions.o +++ /dev/null |