static int cf_file_fill(cf_stack_t *stack);
-static uint8_t const *skip_string(uint8_t const *p, char c)
-{
- while (*p >= ' ') {
- if (*p == c) {
- p++;
- return p;
- }
-
- if (*p != '\\') {
- p++;
- continue;
- }
-
- if (p[1] < ' ') {
- return NULL;
- }
-
- if (!isdigit((int) p[1])) {
- p += 2;
- continue;
- }
-
- /*
- * Double-quoted strings use \000
- * Regexes use \0
- */
- if (c == '/') {
- p++;
- continue;
- }
-
- if (!isdigit((int) p[2]) || !isdigit((int) p[3])) {
- return NULL;
- }
-
- p += 4;
- }
-
- return NULL;
-}
-
/*
* Expansions can contain other expansions, but can't contain regexes.
*/
}
if ((*p == '"') || (*p == '\'') || (*p == '`')) {
- char c = *p++;
+ ssize_t slen;
- p = skip_string(p, c);
- if (!p) return NULL;
+ slen = fr_skip_string((char const *) p, NULL);
+ if (slen <= 0) return NULL;
+
+ p += slen;
continue;
}
*
*/
while (true) {
- char c;
bool found = false;
bool was_regex = false;
int depth = 0;
* We have a quoted string, ignore '(' and ')' within it.
*/
if ((*p == '"') || (*p == '\'') || (*p == '`') || (was_regex && (*p == '/'))) {
+ ssize_t my_slen;
+
was_regex = false;
- c = *p++;
- p = skip_string(p, c);
- if (!p) {
+
+ my_slen = fr_skip_string((char const *) p, NULL);
+ if (my_slen <= 0) {
cf_log_err(cs, "Unexpected end of string");
talloc_free(cs);
return NULL;
}
+ p += my_slen;
continue;
}
}
+/** Skip a quoted string.
+ *
+ * @param[in] start start of the string, pointing to the quotation character
+ * @param[in] end end of the string (or NULL for zero-terminated strings)
+ * @return
+ * >0 length of the string which was parsed
+ * <=0 on error
+ */
ssize_t fr_skip_string(char const *start, char const *end)
{
char const *p = start;
quote = *(p++);
- while (p < end) {
+ while ((end && (p < end)) || *p) {
+ /*
+ * Stop at the quotation character
+ */
if (*p == quote) {
p++;
return p - start;
}
- if (*p == '\\') {
- if (((p + 1) >= end) || !p[1]) {
- break;
- }
+ /*
+ * Not an escape character: it's OK.
+ */
+ if (*p != '\\') {
+ p++;
+ continue;
+ }
+ if (end && ((p + 2) >= end)) {
+ fail:
+ fr_strerror_const("Unexpected escape at end of string");
+ return -(p - start);
+ }
+
+ /*
+ * Escape at EOL is not allowed.
+ */
+ if (p[1] < ' ') goto fail;
+
+ /*
+ * \r or \n, etc.
+ */
+ if (!isdigit((int) p[1])) {
p += 2;
continue;
}
- p++;
+ /*
+ * Double-quoted strings use \000
+ * Regexes use \0
+ */
+ if (quote == '/') {
+ p++;
+ continue;
+ }
+
+ if (end && ((p + 4) >= end)) goto fail;
+
+ if (!isdigit((int) p[2]) || !isdigit((int) p[3])) {
+ fr_strerror_const("Invalid octal escape");
+ return -(p - start);
+ }
+
+ p += 4;
}
/*
fr_strerror_const("Unexpected end of string");
return -(p - start);
}
+