non existence of RR types at the root. Thanks ZjYwMj
* Set NSEC(3) ttls to the minimum of the MINIMUM field of the SOA
record and the TTL of the SOA itself. draft-ietf-dnsop-nsec-ttl
+ * bugfix #119: Let example tools read longer RR's than
+ LDNS_MAX_LINELEN
1.7.1 2019-07-26
* bugfix: Manage verification paths for OpenSSL >= 1.1.0
*/
ssize_t ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr);
+/**
+ * returns a token/char from the stream f.
+ * This function deals with ( and ) in the stream,
+ * and ignores when it finds them.
+ * \param[in] *f the file to read from
+ * \param[out] **token this should be a reference to a string buffer in which
+ * the token is put. A new buffer will be allocated when
+ * *token is NULL and fixed is false. If the buffer is too
+ * small to hold the token, the buffer is reallocated with
+ * double the size (of limit).
+ * If fixed is true, the string buffer may not be NULL
+ * and limit must be set to the buffer size. In that case
+ * no reallocations will be done.
+ * \param[in,out] *limit reference to the size of the token buffer. Will be
+ * reset to the new limit of the token buffer if the
+ * buffer is reallocated.
+ * \param [in] fixed If fixed is false, the token buffer is allowed to grow
+ * when needed (by way of reallocation). If true, the token
+ * buffer will not be resized.
+ * \param[in] *delim chars at which the parsing should stop
+ * \param[in] line_nr pointer to an integer containing the current line number (for debugging purposes)
+ * \return LDNS_STATUS_OK on success, LDNS_STATUS_SYNTAX_EMPTY when no token
+ * was read and an error otherwise.
+ */
+ldns_status ldns_fget_token_l_st(FILE *f, char **token, size_t *limit, bool fixed, const char *delim, int *line_nr);
+
/**
* returns a token/char from the buffer b.
* This function deals with ( and ) in the buffer,
return ldns_fget_token_l(f, token, delim, limit, NULL);
}
-ssize_t
-ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
+ldns_status
+ldns_fget_token_l_st(FILE *f, char **token, size_t *limit, bool fixed
+ , const char *delim, int *line_nr)
{
int c, prev_c;
int p; /* 0 -> no parenthese seen, >0 nr of ( seen */
int com, quoted;
- char *t;
+ char *t, *old_token;
size_t i;
const char *d;
const char *del;
} else {
del = delim;
}
+ if (!token || !limit)
+ return LDNS_STATUS_NULL;
+
+ if (fixed) {
+ if (*token == NULL || *limit == 0)
+ return LDNS_STATUS_NULL;
+ } else if (*token == NULL) {
+ *limit = LDNS_MAX_LINELEN;
+ if (!(*token = LDNS_XMALLOC(char, *limit + 1)))
+ return LDNS_STATUS_MEM_ERR;
+
+ } else if (*limit == 0)
+ return LDNS_STATUS_ERR;
p = 0;
i = 0;
com = 0;
quoted = 0;
prev_c = 0;
- t = token;
+ t = *token;
if (del[0] == '"') {
quoted = 1;
}
if (p < 0) {
/* more ) then ( - close off the string */
*t = '\0';
- return 0;
+ return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY
+ : LDNS_STATUS_OK;
}
/* do something with comments ; */
continue;
}
- if (c == '\n' && p != 0 && t > token) {
+ if (c == '\n' && p != 0 && t > *token) {
/* in parentheses */
if (line_nr) {
*line_nr = *line_nr + 1;
}
- if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
- *t = '\0';
- return -1;
+ if (*limit > 0
+ && (i >= *limit || (size_t)(t - *token) >= *limit)) {
+ if (fixed) {
+ *t = '\0';
+ return LDNS_STATUS_SYNTAX_ERR;
+ }
+ old_token = *token;
+ *limit *= 2;
+ *token = LDNS_XREALLOC(*token, char, *limit + 1);
+ if (*token == NULL) {
+ *token = old_token;
+ *t = '\0';
+ return LDNS_STATUS_MEM_ERR;
+ }
+ if (*token != old_token)
+ t = *token + (t - old_token);
}
*t++ = ' ';
prev_c = c;
if (c != '\0' && c != '\n') {
i++;
}
- if (limit > 0 && (i >= limit || (size_t)(t-token) >= limit)) {
- *t = '\0';
- return -1;
+ if (*limit > 0
+ && (i >= *limit || (size_t)(t - *token) >= *limit)) {
+ if (fixed) {
+ *t = '\0';
+ return LDNS_STATUS_SYNTAX_ERR;
+ }
+ old_token = *token;
+ *limit *= 2;
+ *token = LDNS_XREALLOC(*token, char, *limit + 1);
+ if (*token == NULL) {
+ *token = old_token;
+ *t = '\0';
+ return LDNS_STATUS_MEM_ERR;
+ }
+ if (*token != old_token)
+ t = *token + (t - old_token);
}
if (c != '\0' && c != '\n') {
*t++ = c;
}
*t = '\0';
if (c == EOF) {
- return (ssize_t)i;
+ return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
}
- if (i == 0) {
- /* nothing read */
- return -1;
- }
if (p != 0) {
- return -1;
+ return LDNS_STATUS_SYNTAX_ERR;
}
- return (ssize_t)i;
+ return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
tokenread:
if(*del == '"') /* do not skip over quotes, they are significant */
else ldns_fskipcs_l(f, del, line_nr);
*t = '\0';
if (p != 0) {
- return -1;
+ return LDNS_STATUS_SYNTAX_ERR;
}
+ return i == 0 ? LDNS_STATUS_SYNTAX_EMPTY : LDNS_STATUS_OK;
+}
- return (ssize_t)i;
+
+ssize_t
+ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
+{
+ if (ldns_fget_token_l_st(f, &token, &limit, true, delim, line_nr))
+ return -1;
+ else
+ return (ssize_t)strlen(token);
}
ssize_t
ldns_status
ldns_rr_new_frm_fp_l(ldns_rr **newrr, FILE *fp, uint32_t *default_ttl, ldns_rdf **origin, ldns_rdf **prev, int *line_nr)
{
- char *line;
+ char *line = NULL;
+ size_t limit = 0;
const char *endptr; /* unused */
ldns_rr *rr;
uint32_t ttl;
ldns_rdf *tmp;
ldns_status s;
- ssize_t size;
if (default_ttl) {
ttl = *default_ttl;
} else {
ttl = 0;
}
-
- line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1);
- if (!line) {
- return LDNS_STATUS_MEM_ERR;
- }
-
/* read an entire line in from the file */
- if ((size = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, LDNS_MAX_LINELEN, line_nr)) == -1) {
- LDNS_FREE(line);
- /* if last line was empty, we are now at feof, which is not
- * always a parse error (happens when for instance last line
- * was a comment)
- */
- return LDNS_STATUS_SYNTAX_ERR;
- }
-
- /* we can have the situation, where we've read ok, but still got
- * no bytes to play with, in this case size is 0
- */
- if (size == 0) {
- LDNS_FREE(line);
- return LDNS_STATUS_SYNTAX_EMPTY;
- }
+ if ((s = ldns_fget_token_l_st( fp, &line, &limit, false
+ , LDNS_PARSE_SKIP_SPACE, line_nr)))
+ return s;
if (strncmp(line, "$ORIGIN", 7) == 0 && isspace((unsigned char)line[7])) {
if (*origin) {