mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
check_name() determines if IDN processing is needed.
Optimization that only runs IDN processing if it would alter the domain name (non-ascii or uppercase characters). This patch has conributions from Petr Menšík.
This commit is contained in:
committed by
Simon Kelley
parent
6f4de018af
commit
93cf516bf1
60
src/util.c
60
src/util.c
@@ -115,7 +115,8 @@ u64 rand64(void)
|
|||||||
return (u64)out[outleft+1] + (((u64)out[outleft]) << 32);
|
return (u64)out[outleft+1] + (((u64)out[outleft]) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns 2 if names is OK but contains one or more underscores */
|
/* returns 1 if name is OK and ascii printable
|
||||||
|
* returns 2 if name should be processed by IDN */
|
||||||
static int check_name(char *in)
|
static int check_name(char *in)
|
||||||
{
|
{
|
||||||
/* remove trailing .
|
/* remove trailing .
|
||||||
@@ -123,7 +124,9 @@ static int check_name(char *in)
|
|||||||
size_t dotgap = 0, l = strlen(in);
|
size_t dotgap = 0, l = strlen(in);
|
||||||
char c;
|
char c;
|
||||||
int nowhite = 0;
|
int nowhite = 0;
|
||||||
|
int idn_encode = 0;
|
||||||
int hasuscore = 0;
|
int hasuscore = 0;
|
||||||
|
int hasucase = 0;
|
||||||
|
|
||||||
if (l == 0 || l > MAXDNAME) return 0;
|
if (l == 0 || l > MAXDNAME) return 0;
|
||||||
|
|
||||||
@@ -136,28 +139,49 @@ static int check_name(char *in)
|
|||||||
for (; (c = *in); in++)
|
for (; (c = *in); in++)
|
||||||
{
|
{
|
||||||
if (c == '.')
|
if (c == '.')
|
||||||
dotgap = 0;
|
dotgap = 0;
|
||||||
else if (++dotgap > MAXLABEL)
|
else if (++dotgap > MAXLABEL)
|
||||||
return 0;
|
return 0;
|
||||||
else if (isascii((unsigned char)c) && iscntrl((unsigned char)c))
|
else if (isascii((unsigned char)c) && iscntrl((unsigned char)c))
|
||||||
/* iscntrl only gives expected results for ascii */
|
/* iscntrl only gives expected results for ascii */
|
||||||
return 0;
|
return 0;
|
||||||
#if !defined(HAVE_IDN) && !defined(HAVE_LIBIDN2)
|
|
||||||
else if (!isascii((unsigned char)c))
|
else if (!isascii((unsigned char)c))
|
||||||
return 0;
|
#if !defined(HAVE_IDN) && !defined(HAVE_LIBIDN2)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
idn_encode = 1;
|
||||||
#endif
|
#endif
|
||||||
else if (c != ' ')
|
else if (c != ' ')
|
||||||
{
|
{
|
||||||
nowhite = 1;
|
nowhite = 1;
|
||||||
if (c == '_')
|
#if defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003)
|
||||||
hasuscore = 1;
|
if (c == '_')
|
||||||
}
|
hasuscore = 1;
|
||||||
|
#else
|
||||||
|
(void)hasuscore;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
|
||||||
|
if (c >= 'A' && c <= 'Z')
|
||||||
|
hasucase = 1;
|
||||||
|
#else
|
||||||
|
(void)hasucase;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nowhite)
|
if (!nowhite)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return hasuscore ? 2 : 1;
|
#if defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003)
|
||||||
|
/* Older libidn2 strips underscores, so don't do IDN processing
|
||||||
|
if the name has an underscore unless it also has non-ascii characters. */
|
||||||
|
idn_encode = idn_encode || (hasucase && !hasuscore);
|
||||||
|
#else
|
||||||
|
idn_encode = idn_encode || hasucase;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (idn_encode) ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hostnames have a more limited valid charset than domain names
|
/* Hostnames have a more limited valid charset than domain names
|
||||||
@@ -204,12 +228,8 @@ char *canonicalise(char *in, int *nomem)
|
|||||||
if (!(rc = check_name(in)))
|
if (!(rc = check_name(in)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#if defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003)
|
|
||||||
/* older libidn2 strips underscores, so don't do IDN processing
|
|
||||||
if the name has an underscore (check_name() returned 2) */
|
|
||||||
if (rc != 2)
|
|
||||||
#endif
|
|
||||||
#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
|
#if defined(HAVE_IDN) || defined(HAVE_LIBIDN2)
|
||||||
|
if (rc == 2)
|
||||||
{
|
{
|
||||||
# ifdef HAVE_LIBIDN2
|
# ifdef HAVE_LIBIDN2
|
||||||
rc = idn2_to_ascii_lz(in, &ret, IDN2_NONTRANSITIONAL);
|
rc = idn2_to_ascii_lz(in, &ret, IDN2_NONTRANSITIONAL);
|
||||||
@@ -234,12 +254,14 @@ char *canonicalise(char *in, int *nomem)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
(void)rc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((ret = whine_malloc(strlen(in)+1)))
|
if ((ret = whine_malloc(strlen(in)+1)))
|
||||||
strcpy(ret, in);
|
strcpy(ret, in);
|
||||||
else if (nomem)
|
else if (nomem)
|
||||||
*nomem = 1;
|
*nomem = 1;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user