{ LDNS_STATUS_SYNTAX_ITERATIONS_OVERFLOW, "Iterations count for NSEC3 record higher than maximum" },
{ LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR, "Syntax error, value expected" },
{ LDNS_STATUS_SYNTAX_INTEGER_OVERFLOW, "Syntax error, integer value too large" },
+ { LDNS_STATUS_SYNTAX_BAD_ESCAPE, "Syntax error, bad escape sequence" },
{ LDNS_STATUS_SOCKET_ERROR, "Error creating socket" },
{ LDNS_STATUS_DNSSEC_EXISTENCE_DENIED, "Existence denied by NSEC" },
{ LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED, "RR not covered by the given NSEC RRs" },
}
}
+
+/*
+ * Checks whether the escaped value at **s is an octal value or
+ * a 'normally' escaped character (and not eos)
+ *
+ * The string pointer at *s is increased by either 0 (on error), 1 (on
+ * normal escapes), or 3 (on octals)
+ *
+ * Returns the number of bytes read from the escaped string, or
+ * 0 on error
+ */
+static int
+parse_escape(uint8_t *s, uint8_t *q) {
+ uint8_t val;
+ if (strlen((char *)s) > 3 &&
+ isdigit((int) s[1]) &&
+ isdigit((int) s[2]) &&
+ isdigit((int) s[3])) {
+ /* cast this so it fits */
+ val = (uint8_t) ldns_hexdigit_to_int((char) s[1]) * 100 +
+ ldns_hexdigit_to_int((char) s[2]) * 10 +
+ ldns_hexdigit_to_int((char) s[3]);
+ *q = val;
+ return 3;
+ } else {
+ s++;
+ if (*s == '\0') {
+ /* apparently the string terminator
+ * has been escaped...
+ */
+ return 0;
+ }
+ *q = *s;
+ return 1;
+ }
+}
+
/*
* No special care is taken, all dots are translated into
* label seperators.
{
size_t len;
- uint8_t *s,*p,*q, *pq, val, label_len;
+ int esc;
+ uint8_t *s,*p,*q, *pq, label_len;
uint8_t buf[LDNS_MAX_DOMAINLEN + 1];
*d = NULL;
break;
case '\\':
/* octet value or literal char */
- if (strlen((char *)s) > 3 &&
- isdigit((int) s[1]) &&
- isdigit((int) s[2]) &&
- isdigit((int) s[3])) {
- /* cast this so it fits */
- val = (uint8_t) ldns_hexdigit_to_int((char) s[1]) * 100 +
- ldns_hexdigit_to_int((char) s[2]) * 10 +
- ldns_hexdigit_to_int((char) s[3]);
- *q = val;
- s += 3;
+ esc = parse_escape(s, q);
+ if (esc > 0) {
+ s += esc;
+ label_len++;
} else {
- s++;
- *q = *s;
+ return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
}
- label_len++;
break;
default:
*q = *s;
ldns_str2rdf_str(ldns_rdf **rd, const char *str)
{
uint8_t *data;
- uint8_t val;
size_t i, str_i;
+ int esc;
if (strlen(str) > 255) {
return LDNS_STATUS_INVALID_STR;
i = 1;
for (str_i = 0; str_i < strlen(str); str_i++) {
if (str[str_i] == '\\') {
- if(str_i + 3 < strlen(str) &&
- isdigit((int) str[str_i + 1]) &&
- isdigit((int) str[str_i + 2]) &&
- isdigit((int) str[str_i + 3])) {
- val = (uint8_t) ldns_hexdigit_to_int((char) str[str_i + 1]) * 100 +
- ldns_hexdigit_to_int((char) str[str_i + 2]) * 10 +
- ldns_hexdigit_to_int((char) str[str_i + 3]);
- data[i] = val;
+ esc = parse_escape(str + str_i, data + i);
+ if (esc > 0) {
+ str_i += esc;
i++;
- str_i += 3;
} else {
- str_i++;
- data[i] = (uint8_t) str[str_i];
- i++;
+ LDNS_FREE(data);
+ *rd = NULL;
+ return LDNS_STATUS_SYNTAX_BAD_ESCAPE;
}
} else {
data[i] = (uint8_t) str[str_i];