Don't do \n --> CR mashing in xlat.c
authorAlan T. DeKok <aland@freeradius.org>
Mon, 27 Oct 2014 20:32:04 +0000 (16:32 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 27 Oct 2014 20:32:04 +0000 (16:32 -0400)
As it turns out, it's almost always wrong.  The correct escaping
rules are that the conf file parser reads a string, and that string
is passed verbatim through all of the layers to the final consumer.

Only the final consumer does the mashing of \n --> CR.

This means that the tests are currently broken.

%{md5:...\n} expects to get a CR on input, and it now gets a "\n".
Fixing that is the next stage.

src/main/xlat.c
src/tests/unit/xlat.txt

index 6068fce..4145ada 100644 (file)
@@ -1105,7 +1105,7 @@ static ssize_t xlat_tokenize_expansion(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **
 static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **head,
                                     int brace, char const **error)
 {
-       char *p, *q;
+       char *p;
        xlat_exp_t *node;
 
        if (!*fmt) return 0;
@@ -1118,58 +1118,15 @@ static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **he
        node->type = XLAT_LITERAL;
 
        p = fmt;
-       q = fmt;
 
        while (*p) {
-               /*
-                *      Convert \n to it's literal representation.
-                */
-               if (p[0] == '\\') switch (p[1]) {
-               case 't':
-                       *(q++) = '\t';
-                       p += 2;
-                       node->len++;
-                       continue;
-
-               case 'n':
-                       *(q++) = '\n';
-                       p += 2;
-                       node->len++;
-                       continue;
-
-               case 'x':
-                       p += 2;
-                       if (!p[0] || !p[1]) {
-                               talloc_free(node);
-                               *error = "Hex expansion requires two hex digits";
-                               return -(p - fmt);
-                       }
-
-                       if (!fr_hex2bin((uint8_t *) q, 1, p, 2)) {
-                               talloc_free(node);
-                               *error = "Invalid hex characters";
-                               return -(p - fmt);
-                       }
-
-                       /*
-                        *      Don't let people shoot themselves in the foot.
-                        *      \x00 is forbidden.
-                        */
-                       if (!*q) {
+               if (*p == '\\') {
+                       if (!p[1]) {
                                talloc_free(node);
-                               *error = "Cannot add zero byte to printable string";
+                               *error = "Invalid escape at end of string";
                                return -(p - fmt);
                        }
-
                        p += 2;
-                       q++;
-                       node->len++;
-                       continue;
-
-               default:
-                       *(q++) = *p;
-                       p += 2;
-                       node->len++;
                        continue;
                }
 
@@ -1269,12 +1226,12 @@ static ssize_t xlat_tokenize_literal(TALLOC_CTX *ctx, char *fmt, xlat_exp_t **he
                 *      If required, eat the brace.
                 */
                if (brace && (*p == '}')) {
-                       *q = '\0';
+                       *p = '\0';
                        p++;
                        break;
                }
 
-               *(q++) = *(p++);
+               p++;
                node->len++;
        }
 
@@ -2029,6 +1986,10 @@ static char *xlat_aprint(TALLOC_CTX *ctx, REQUEST *request, xlat_exp_t const * c
                str = talloc_array(ctx, char, 2048); /* FIXME: have the module call talloc_typed_asprintf */
                *str = '\0';    /* Be sure the string is NULL terminated, we now only free on error */
 
+               /*
+                *      Convert \n --> CR if requested.
+                */
+
                rcode = node->xlat->func(node->xlat->instance, request, child, str, 2048);
                talloc_free(child);
                if (rcode < 0) {
index 698d8f2..e66d96a 100644 (file)
@@ -125,3 +125,6 @@ data "%{reply:3GPP-IMSI}"
 
 xlat "%{reply:3GPP-IMSI[2]}"
 data "%{reply:3GPP-IMSI[2]}"
+
+xlat /([A-Z0-9\-]*)_%{Calling-Station-Id}/
+data /([A-Z0-9\-]*)_%{Calling-Station-Id}/