|  | @@ -443,6 +443,211 @@ START_TEST(test_match_prefix_strlen)
 | 
											
												
													
														|  |  	ck_assert_int_eq(15,
 |  |  	ck_assert_int_eq(15,
 | 
											
												
													
														|  |  	                 match_prefix_strlen("**.jpg$|**.jpeg$",
 |  |  	                 match_prefix_strlen("**.jpg$|**.jpeg$",
 | 
											
												
													
														|  |  	                                     "/sub/image.jpeg"));
 |  |  	                                     "/sub/image.jpeg"));
 | 
											
												
													
														|  | 
 |  | +	ck_assert_int_eq(14,
 | 
											
												
													
														|  | 
 |  | +	                 match_prefix_strlen("/*/*.jpg$|/*/*.jpeg$",
 | 
											
												
													
														|  | 
 |  | +	                                     "/sub/image.jpg"));
 | 
											
												
													
														|  | 
 |  | +	ck_assert_int_eq(15,
 | 
											
												
													
														|  | 
 |  | +	                 match_prefix_strlen("/*/*.jpg$|/*/*.jpeg$",
 | 
											
												
													
														|  | 
 |  | +	                                     "/sub/image.jpeg"));
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +END_TEST
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +START_TEST(test_match_prefix_fuzz)
 | 
											
												
													
														|  | 
 |  | +{
 | 
											
												
													
														|  | 
 |  | +	/* Copyright (c) 2022 the CivetWeb developers */
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "**cacc//d/?dad?";
 | 
											
												
													
														|  | 
 |  | +		const char *str =
 | 
											
												
													
														|  | 
 |  | +		    "dbbddb/cb/ddcdbcbbab/dcdcbbbcaaacdbcac/dbdcadaa/bcaca/d/a/adcad";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(6, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(61, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(62, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(52, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "a/a*d**/?*/*cdd";
 | 
											
												
													
														|  | 
 |  | +		const char *str =
 | 
											
												
													
														|  | 
 |  | +		    "a/aaddba/ddadbaacac//bcaadbc/badaccbdadadcbb//ccd/dcbacdcddc//c";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 0, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(1, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(2, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(3, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(8, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(6, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(8, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 7, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(62, match_prefix(pat, 8, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 9, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 10, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(61, match_prefix(pat, 11, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(61, match_prefix(pat, 12, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(60, match_prefix(pat, 13, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(58, match_prefix(pat, 14, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(59, match_prefix(pat, 15, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(59, match_prefix_strlen(pat, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "cc/?**ba????**b";
 | 
											
												
													
														|  | 
 |  | +		const char *str =
 | 
											
												
													
														|  | 
 |  | +		    "cc/babdb/cbb/baa/da/cd///ccabbcdcdaa/dbacbdbadaccb/dbdcc/cdbbac";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 0, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(1, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(2, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(3, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(4, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(8, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(61, match_prefix(pat, 7, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(62, match_prefix(pat, 8, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 9, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(47, match_prefix(pat, 10, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(48, match_prefix(pat, 11, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(49, match_prefix(pat, 12, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(50, match_prefix(pat, 13, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 14, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(61, match_prefix(pat, 15, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(61, match_prefix_strlen(pat, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "?**ba*db*b?*/a?";
 | 
											
												
													
														|  | 
 |  | +		const char *str =
 | 
											
												
													
														|  | 
 |  | +		    "bd/bcdddabbd//bcb//acbcaaac/dcbbcdadabadba/bd/baadbabcc/a/bcb//";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 0, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(1, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(2, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(61, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(52, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(55, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(50, match_prefix(pat, 7, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(51, match_prefix(pat, 8, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(55, match_prefix(pat, 9, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(53, match_prefix(pat, 10, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(54, match_prefix(pat, 11, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(55, match_prefix(pat, 12, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(56, match_prefix(pat, 13, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(57, match_prefix(pat, 14, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix(pat, 15, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix_strlen(pat, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "?b*da*bc?c**//*";
 | 
											
												
													
														|  | 
 |  | +		const char *str =
 | 
											
												
													
														|  | 
 |  | +		    "dbadabcbcbbba/a///d//dcdd////daccbcaaa/a/bacddab/bdcbbdd/bbaa/a";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 0, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(1, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(2, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(13, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(4, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(5, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(13, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(12, match_prefix(pat, 7, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(9, match_prefix(pat, 8, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(10, match_prefix(pat, 9, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(9, match_prefix(pat, 10, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(13, match_prefix(pat, 11, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(63, match_prefix(pat, 12, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(62, match_prefix(pat, 13, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(29, match_prefix(pat, 14, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(38, match_prefix(pat, 15, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(38, match_prefix_strlen(pat, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "?**c**dc**b*c*a";
 | 
											
												
													
														|  | 
 |  | +		const char *str = "cba/a/bbcdcccc/bcacacdadab/dad/";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 0, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(1, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(3, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(31, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(21, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(26, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(31, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(30, match_prefix(pat, 7, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(11, match_prefix(pat, 8, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(14, match_prefix(pat, 9, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(31, match_prefix(pat, 10, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(26, match_prefix(pat, 11, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(26, match_prefix(pat, 12, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(21, match_prefix(pat, 13, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(26, match_prefix(pat, 14, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(25, match_prefix(pat, 15, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(25, match_prefix_strlen(pat, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "$|*ca|**c/c*b|a";
 | 
											
												
													
														|  | 
 |  | +		const char *str = "bcdaa/a//acdc/bac/caacacdcbcdc/";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 0, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(5, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(2, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(5, match_prefix(pat, 7, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(31, match_prefix(pat, 8, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(30, match_prefix(pat, 9, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(31, match_prefix(pat, 10, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(19, match_prefix(pat, 11, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(30, match_prefix(pat, 12, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(27, match_prefix(pat, 13, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(27, match_prefix(pat, 14, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(27, match_prefix(pat, 15, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(27, match_prefix_strlen(pat, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "*b?c|?$|*b?b**?";
 | 
											
												
													
														|  | 
 |  | +		const char *str = "cbbbddddda/dbcdbbbccdcb/a//ddab";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 0, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(10, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(4, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(5, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(1, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix(pat, 7, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 8, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(10, match_prefix(pat, 9, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(4, match_prefix(pat, 10, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(5, match_prefix(pat, 11, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(4, match_prefix(pat, 12, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(10, match_prefix(pat, 13, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(31, match_prefix(pat, 14, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(31, match_prefix(pat, 15, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(31, match_prefix_strlen(pat, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	{
 | 
											
												
													
														|  | 
 |  | +		/* From fuzz test */
 | 
											
												
													
														|  | 
 |  | +		const char *pat = "c|b?*$|*ca*/*ba";
 | 
											
												
													
														|  | 
 |  | +		const char *str = "bdccacb/aaadbadd/ccaca/c/cdcb/d";
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 0, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix(pat, 1, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 2, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(1, match_prefix(pat, 3, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(2, match_prefix(pat, 4, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(7, match_prefix(pat, 5, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(-1, match_prefix(pat, 6, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(0, match_prefix(pat, 7, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(7, match_prefix(pat, 8, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(6, match_prefix(pat, 9, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(5, match_prefix(pat, 10, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(7, match_prefix(pat, 11, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(8, match_prefix(pat, 12, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(16, match_prefix(pat, 13, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(13, match_prefix(pat, 14, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(14, match_prefix(pat, 15, str));
 | 
											
												
													
														|  | 
 |  | +		ck_assert_int_eq(14, match_prefix_strlen(pat, str));
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  END_TEST
 |  |  END_TEST
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -1489,6 +1694,7 @@ make_private_suite(void)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	tcase_add_test(tcase_url_parsing_1, test_match_prefix);
 |  |  	tcase_add_test(tcase_url_parsing_1, test_match_prefix);
 | 
											
												
													
														|  |  	tcase_add_test(tcase_url_parsing_1, test_match_prefix_strlen);
 |  |  	tcase_add_test(tcase_url_parsing_1, test_match_prefix_strlen);
 | 
											
												
													
														|  | 
 |  | +	tcase_add_test(tcase_url_parsing_1, test_match_prefix_fuzz);
 | 
											
												
													
														|  |  	tcase_set_timeout(tcase_url_parsing_1, civetweb_min_test_timeout);
 |  |  	tcase_set_timeout(tcase_url_parsing_1, civetweb_min_test_timeout);
 | 
											
												
													
														|  |  	suite_add_tcase(suite, tcase_url_parsing_1);
 |  |  	suite_add_tcase(suite, tcase_url_parsing_1);
 | 
											
												
													
														|  |  
 |  |  
 |