summaryrefslogtreecommitdiff
path: root/conf
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-08-24 02:20:19 +0200
commit1accc4d5c84bc10e9c116e76d04785377e40fff4 (patch)
treea8c61efedbeebb15bb962125a945e9ca7545afc7 /conf
parent400f19d44a26061933a9991a7f5765835acc5cdc (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')
-rw-r--r--conf/cf-lex.l59
-rw-r--r--conf/confbase.Y9
2 files changed, 67 insertions, 1 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 9025a84d..176c1432 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"
struct keyword {
byte *name;
@@ -124,10 +125,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]
@@ -372,6 +374,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 BYTESTRING;
+}
+
+<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 BYTESTRING;
+}
+
+<B64QUOTED>. BUFFER_PUSH(quoted_buffer) = yytext[0];
+
<INITIAL,COMMENT><<EOF>> { if (check_eof()) return END; }
{WHITE}+
diff --git a/conf/confbase.Y b/conf/confbase.Y
index 3dd5fed7..0c53f7ec 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -117,6 +117,7 @@ CF_DECLS
%type <mls> label_stack_start label_stack
%type <t> text opttext
+%type <bs> bytestring
%type <s> symbol
%type <kw> kw_sym
@@ -395,6 +396,14 @@ opttext:
| /* empty */ { $$ = NULL; }
;
+bytestring:
+ BYTESTRING
+ | CF_SYM_KNOWN {
+ if ($1->class != (SYM_CONSTANT | T_BYTESTRING)) cf_error("Bytestring constant expected");
+ $$ = SYM_VAL($1).bs;
+ }
+ ;
+
CF_CODE