Skip to content

Commit

Permalink
add and document support for tripled-quoted strings
Browse files Browse the repository at this point in the history
	secret = """foo " bar " baz ! """
  • Loading branch information
alandekok committed Nov 22, 2024
1 parent d92fcd0 commit 888bda7
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 9 deletions.
2 changes: 1 addition & 1 deletion doc/antora/modules/reference/pages/type/all_types.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ possible to write values in the format you expect, The server will do
| ipv4prefix | IPv4 network with address and prefix length
| ipv6prefix | IPv6 network with address and prefix length
| octets | raw binary, printed as hex strings
| string | printable strings
| xref:type/string/index.adoc[string] | printable strings
| time_delta | difference between two calendar dates
| uint8 | 8-bit unsigned integer
| uint16 | 16-bit unsigned integer
Expand Down
2 changes: 1 addition & 1 deletion doc/antora/modules/reference/pages/type/index.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
= Data Types

Unlang supports a number of data types. These data types are used in
conditional expressions or when assigning a value to an attribute.
dictionaries, expressions or when assigning a value to an attribute.

== Using Data Types

Expand Down
9 changes: 9 additions & 0 deletions doc/antora/modules/reference/pages/type/string/double.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ xref:xlat/index.adoc[dynamic expansions]. As with
xref:type/string/single.adoc[single-quoted strings], text within
double quotes can include spaces.

For normally quoted strings, the quotation character can be placed inside of
the string by escaping it with a backslash.

For triple quoted strings, the quotation character does not need to be
escaped. However, if the string does contain an escaped quotation
character, the quotation character is unescaped, as with normally
quoted strings.

The main difference between the single and double quoted strings is
that the double quoted strings can be dynamically expanded. The syntax
`${...}` is used for parse-time expansion and `%{...}` is used for
Expand Down Expand Up @@ -133,6 +141,7 @@ string is being used.
`"this has embedded\ncharacters"` +
`"attribute\tvalue\nusername\t%{User-Name}\nreply-message\t%{reply.Reply-Message}"`
`"The result of 'SELECT * FROM foo WHERE 1' is: %sql(SELECT * FROM foo WHERE 1)"`
`"""this string has a "double quoted" string in the middle of it"""`

// Licenced under CC-by-NC 4.0.
// Copyright (C) 2019 Arran Cudbard-Bell <[email protected]>
Expand Down
13 changes: 11 additions & 2 deletions doc/antora/modules/reference/pages/type/string/single.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,27 @@

.Syntax
`'string'`
`'''string with 'quote' embedded'''`

A single-quoted string is interpreted without any dynamic string
expansion. The quotes allow the string to contain spaces, among other
special characters. The single quote character can be placed in such a
string by escaping it with a backslash.
special characters.

For normally quoted strings, the quotation character can be placed inside of
the string by escaping it with a backslash.

For triple quoted strings, the quotation character does not need to be
escaped. However, if the string does contain an escaped quotation
character, the quotation character is unescaped, as with normally
quoted strings.

.Examples

`'hello'` +
`'foo bar`' +
`'foo\\'bar'` +
`'this is a long string'`
`'''This is a string with 'embedded' quotes'''`

// Copyright (C) 2021 Network RADIUS SAS. Licenced under CC-by-NC 4.0.
// This documentation was developed by Network RADIUS SAS.
27 changes: 25 additions & 2 deletions src/lib/server/tmpl_tokenize.c
Original file line number Diff line number Diff line change
Expand Up @@ -5352,6 +5352,7 @@ ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t i
char quote;
char close;
int depth;
bool triple;

*type = T_INVALID;

Expand Down Expand Up @@ -5496,18 +5497,39 @@ ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t i
* more rigorous check.
*/
skip_string:
if ((inlen > 3) && (p[0] == quote) && (p[1] == quote)) {
triple = true;
p += 2;
} else {
triple = false;
}
*out = p;

while (*p) {
if (p >= end) goto unterminated;

/*
* End of string. Tell the caller the
* length of the data inside of the
* string, and return the number of
* characters to skip.
*/
if (*p == quote) {
*outlen = p - (*out);
if (!triple) {
*outlen = p - (*out);
p++;
return p - in;

}

if (((end - p) >= 3) && (p[1] == quote) && (p[2] == quote)) {
*outlen = p - (*out);
p += 3;
return p - in;
}

p++;
return p - in;
continue;
}

if (*p == '\\') {
Expand All @@ -5523,6 +5545,7 @@ ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *in, size_t i
* End of input without end of string.
* Point the error to the start of the string.
*/
unterminated:
p = *out;
return_P("Unterminated string");

Expand Down
27 changes: 24 additions & 3 deletions src/lib/util/token.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ static fr_token_t getthing(char const **ptr, char *buf, int buflen, bool tok,
char *s;
char const *p;
char quote;
bool triple = false;
unsigned int x;
size_t i;
fr_token_t token;
Expand Down Expand Up @@ -315,6 +316,14 @@ static fr_token_t getthing(char const **ptr, char *buf, int buflen, bool tok,

if (token != T_BARE_WORD) {
quote = *p;

/*
* Triple-quoted strings are copied over verbatim, without escapes.
*/
if ((buflen >= 3) && (p[1] == quote) && (p[2] == quote)) {
p += 3;
}

p++;
}
s = buf;
Expand Down Expand Up @@ -350,9 +359,21 @@ static fr_token_t getthing(char const **ptr, char *buf, int buflen, bool tok,
* Un-escaped quote character. We're done.
*/
if (*p == quote) {
p++;
*s++ = 0;
goto done;
if (!triple) {
p++;
*s++ = 0;
goto done;

}

if ((buflen >= 3) && (p[1] == quote) && (p[2] == quote)) {
p += 3;
*s++ = 0;
goto done;
}

*s++ = *p++;
continue;
}

/*
Expand Down

0 comments on commit 888bda7

Please sign in to comment.