mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 22:15:20 +00:00
allow name downcasing inplace or to another name
This commit is contained in:
@@ -789,14 +789,30 @@ dns_result_t dns_name_totext(dns_name_t *name,
|
|||||||
* DNS_R_NOSPACE
|
* DNS_R_NOSPACE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
isc_result_t
|
||||||
dns_name_downcase(dns_name_t *name);
|
dns_name_downcase(dns_name_t *source, dns_name_t *name,
|
||||||
|
isc_buffer_t *target);
|
||||||
/*
|
/*
|
||||||
* Convert all uppercase letters in name to lowercase.
|
* Downcase 'source'.
|
||||||
*
|
*
|
||||||
* Requires:
|
* Requires:
|
||||||
*
|
*
|
||||||
* 'name' is a valid name that is not read-only.
|
* 'source' and 'name' are valid names.
|
||||||
|
*
|
||||||
|
* If source == name, then
|
||||||
|
*
|
||||||
|
* 'source' must not be read-only
|
||||||
|
*
|
||||||
|
* Otherwise,
|
||||||
|
*
|
||||||
|
* 'target' is a valid buffer of type ISC_BUFFERTYPE_BINARY, or
|
||||||
|
* 'target' is NULL and 'name' has a dedicated buffer.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* DNS_R_SUCCESS
|
||||||
|
* DNS_R_NOSPACE
|
||||||
|
*
|
||||||
|
* Note: if source == name, then the result will always be DNS_R_SUCCESS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dns_result_t dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix,
|
dns_result_t dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix,
|
||||||
|
@@ -1724,33 +1724,61 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
|
|||||||
return (DNS_R_SUCCESS);
|
return (DNS_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
isc_result_t
|
||||||
dns_name_downcase(dns_name_t *name) {
|
dns_name_downcase(dns_name_t *source, dns_name_t *name,
|
||||||
unsigned char *ndata;
|
isc_buffer_t *target)
|
||||||
|
{
|
||||||
|
unsigned char *sndata, *ndata;
|
||||||
unsigned int nlen, count, bytes, labels;
|
unsigned int nlen, count, bytes, labels;
|
||||||
|
isc_buffer_t buffer;
|
||||||
|
|
||||||
REQUIRE(VALID_NAME(name));
|
/*
|
||||||
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
|
* Downcase 'source'.
|
||||||
|
*/
|
||||||
|
|
||||||
ndata = name->ndata;
|
REQUIRE(VALID_NAME(source));
|
||||||
nlen = name->length;
|
REQUIRE(VALID_NAME(name));
|
||||||
labels = name->labels;
|
if (source == name) {
|
||||||
|
REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0);
|
||||||
|
isc_buffer_init(&buffer, source->ndata, source->length,
|
||||||
|
ISC_BUFFERTYPE_BINARY);
|
||||||
|
target = &buffer;
|
||||||
|
ndata = source->ndata;
|
||||||
|
} else {
|
||||||
|
REQUIRE(BINDABLE(name));
|
||||||
|
if (target == NULL && name->buffer != NULL) {
|
||||||
|
target = name->buffer;
|
||||||
|
isc_buffer_clear(name->buffer);
|
||||||
|
}
|
||||||
|
ndata = (unsigned char *)target->base + target->used;
|
||||||
|
name->ndata = ndata;
|
||||||
|
}
|
||||||
|
|
||||||
|
sndata = source->ndata;
|
||||||
|
nlen = source->length;
|
||||||
|
labels = source->labels;
|
||||||
|
|
||||||
|
if (nlen > (target->length - target->used)) {
|
||||||
|
MAKE_EMPTY(name);
|
||||||
|
return (DNS_R_NOSPACE);
|
||||||
|
}
|
||||||
|
|
||||||
while (labels > 0 && nlen > 0) {
|
while (labels > 0 && nlen > 0) {
|
||||||
labels--;
|
labels--;
|
||||||
count = *ndata++;
|
count = *sndata++;
|
||||||
|
*ndata++ = count;
|
||||||
nlen--;
|
nlen--;
|
||||||
if (count < 64) {
|
if (count < 64) {
|
||||||
INSIST(nlen >= count);
|
INSIST(nlen >= count);
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
*ndata = maptolower[(*ndata)];
|
*ndata++ = maptolower[(*sndata++)];
|
||||||
ndata++;
|
|
||||||
nlen--;
|
nlen--;
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
} else if (count == DNS_LABELTYPE_BITSTRING) {
|
} else if (count == DNS_LABELTYPE_BITSTRING) {
|
||||||
INSIST(nlen > 0);
|
INSIST(nlen > 0);
|
||||||
count = *ndata++;
|
count = *sndata++;
|
||||||
|
*ndata++ = count;
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
count = 256;
|
count = 256;
|
||||||
nlen--;
|
nlen--;
|
||||||
@@ -1758,17 +1786,33 @@ dns_name_downcase(dns_name_t *name) {
|
|||||||
bytes = count / 8;
|
bytes = count / 8;
|
||||||
if (count % 8 != 0)
|
if (count % 8 != 0)
|
||||||
bytes++;
|
bytes++;
|
||||||
INSIST(nlen >= bytes);
|
|
||||||
|
|
||||||
/* Skip this label */
|
INSIST(nlen >= bytes);
|
||||||
nlen -= bytes;
|
nlen -= bytes;
|
||||||
ndata += bytes;
|
while (bytes > 0) {
|
||||||
|
*ndata++ = *sndata++;
|
||||||
|
bytes--;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
FATAL_ERROR(__FILE__, __LINE__,
|
FATAL_ERROR(__FILE__, __LINE__,
|
||||||
"Unexpected label type %02x", count);
|
"Unexpected label type %02x", count);
|
||||||
/* Does not return. */
|
/* Does not return. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (source != name) {
|
||||||
|
name->labels = source->labels;
|
||||||
|
name->length = source->length;
|
||||||
|
if ((source->attributes & DNS_NAMEATTR_ABSOLUTE) != 0)
|
||||||
|
name->attributes = DNS_NAMEATTR_ABSOLUTE;
|
||||||
|
else
|
||||||
|
name->attributes = 0;
|
||||||
|
if (name->labels > 0 && name->offsets != NULL)
|
||||||
|
set_offsets(name, name->offsets, ISC_FALSE, ISC_FALSE,
|
||||||
|
ISC_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Reference in New Issue
Block a user