summaryrefslogtreecommitdiff
path: root/conf/cf-lex.l
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2021-08-31 13:02:13 +0200
committerMikael Magnusson <mikma@users.sourceforge.net>2023-11-23 01:40:56 +0100
commit788e495561d7bbc8b73f8f512328c567ee487478 (patch)
treee4b9c9d217369628a3c2653112c20aa71da66876 /conf/cf-lex.l
parentef0264cbe83d12976ba43fa64779b777b55e83f9 (diff)
Bytestring: implement bytestring literals and constants
Implement byte string literals on the format b"xxx" and b64"xxx" which can be used as literals and in constants. The format b"xxx" supports character data and octal and hexadecimal data using C escapes (\n, \nn, \nnn, \xn and \xnn). The format b64"xxx" supports base64 encoded strings (RFC1341).
Diffstat (limited to 'conf/cf-lex.l')
-rw-r--r--conf/cf-lex.l59
1 files changed, 58 insertions, 1 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 2f95f2e1..5eb709bc 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -50,6 +50,7 @@
#include "conf/cf-parse.tab.h"
#include "lib/string.h"
#include "lib/hash.h"
+#include "lib/base64.h"
#include "conf/keywords.h"
@@ -111,10 +112,11 @@ static enum yytokentype cf_lex_symbol(const char *data);
%option nounput
%option noreject
-%x COMMENT CCOMM CLI QUOTED APOSTROPHED INCLUDE
+%x COMMENT CCOMM CLI QUOTED BQUOTED B64QUOTED APOSTROPHED INCLUDE
ALPHA [a-zA-Z_]
DIGIT [0-9]
+OIGIT [0-7]
XIGIT [0-9a-fA-F]
ALNUM [a-zA-Z_0-9]
WHITE [ \t]
@@ -343,6 +345,61 @@ else: {
<QUOTED>. BUFFER_PUSH(quoted_buffer) = yytext[0];
+[b]["] {
+ BEGIN(BQUOTED);
+ quoted_buffer_init();
+}
+
+<BQUOTED>\n cf_error("Unterminated byte string");
+<BQUOTED><<EOF>> cf_error("Unterminated byte string");
+<BQUOTED>["] {
+ BEGIN(INITIAL);
+ struct bytestring *bytes;
+
+ bytes = cfg_allocz(sizeof(*bytes) + quoted_buffer.used);
+ memcpy(bytes->data, quoted_buffer.data, quoted_buffer.used);
+ bytes->length = quoted_buffer.used;
+
+ cf_lval.bs = bytes;
+ return BYTETEXT;
+}
+
+<BQUOTED>. BUFFER_PUSH(quoted_buffer) = yytext[0];
+
+<BQUOTED>[\\]({OIGIT}|{OIGIT}{OIGIT}|{OIGIT}{OIGIT}{OIGIT}) {
+ char buf[4];
+ char *end = NULL;
+ memcpy(buf, yytext + 1, yyleng);
+ buf[yyleng] = 0;
+ BUFFER_PUSH(quoted_buffer) = bstrtoul10(buf, &end);
+}
+
+<BQUOTED>[\\][x]({XIGIT}|{XIGIT}{XIGIT}) {
+ char buf[3];
+ char *end = NULL;
+ memcpy(buf, yytext + 2, yyleng);
+ buf[yyleng] = 0;
+ BUFFER_PUSH(quoted_buffer) = bstrtoul16(buf, &end);
+}
+
+[b][6][4]["] {
+ BEGIN(B64QUOTED);
+ quoted_buffer_init();
+}
+
+<B64QUOTED>\n cf_error("Unterminated base64 string");
+<B64QUOTED><<EOF>> cf_error("Unterminated base64 string");
+<B64QUOTED>["] {
+ BEGIN(INITIAL);
+ cf_lval.bs = base64_decode_bs(cfg_mem, quoted_buffer.data, quoted_buffer.used, NULL);
+ if (!cf_lval.bs)
+ cf_error("Invalid base64 string");
+
+ return BYTETEXT;
+}
+
+<B64QUOTED>. BUFFER_PUSH(quoted_buffer) = yytext[0];
+
<INITIAL,COMMENT><<EOF>> { if (check_eof()) return END; }
{WHITE}+