O ponto de interrogação ( ?
) corresponde a um único caractere, incluindo um ponto final. A função usada para comparar nomes de host e ServerAlias
es é ap_strcasecmp_match
(server/util.c:212 ).
// server/util.c
int ap_strcasecmp_match(const char *str, const char *expected)
{
int x, y;
for (x = 0, y = 0; expected[y]; ++y, ++x) {
if (!str[x] && expected[y] != '*')
return -1;
if (expected[y] == '*') {
while (expected[++y] == '*');
if (!expected[y])
return 0;
while (str[x]) {
int ret;
if ((ret = ap_strcasecmp_match(&str[x++], &expected[y])) != 1)
return ret;
}
return -1;
}
else if (expected[y] != '?'
&& apr_tolower(str[x]) != apr_tolower(expected[y]))
return 1;
}
return (str[x] != 'ap_strcasecmp_match("foo.bar.com", "?.bar.com") // 1
ap_strcasecmp_match("f.bar.com", "?.bar.com") // 0
ap_strcasecmp_match("fg.bar.com", "?.bar.com") // 1
ap_strcasecmp_match("..bar.com", "?.bar.com") // 0
ap_strcasecmp_match("f.g.bar.com", "???.bar.com") // 0
');
}
Supondo que faça sentido testar a função isoladamente, é fácil ver que o ponto de interrogação corresponde a caracteres únicos, incluindo pontos finais.
// server/util.c
int ap_strcasecmp_match(const char *str, const char *expected)
{
int x, y;
for (x = 0, y = 0; expected[y]; ++y, ++x) {
if (!str[x] && expected[y] != '*')
return -1;
if (expected[y] == '*') {
while (expected[++y] == '*');
if (!expected[y])
return 0;
while (str[x]) {
int ret;
if ((ret = ap_strcasecmp_match(&str[x++], &expected[y])) != 1)
return ret;
}
return -1;
}
else if (expected[y] != '?'
&& apr_tolower(str[x]) != apr_tolower(expected[y]))
return 1;
}
return (str[x] != 'ap_strcasecmp_match("foo.bar.com", "?.bar.com") // 1
ap_strcasecmp_match("f.bar.com", "?.bar.com") // 0
ap_strcasecmp_match("fg.bar.com", "?.bar.com") // 1
ap_strcasecmp_match("..bar.com", "?.bar.com") // 0
ap_strcasecmp_match("f.g.bar.com", "???.bar.com") // 0
');
}
Um zero é uma correspondência, qualquer outra coisa não é.