From 6cb5f5eb8bd0db3a68c0763fbf0208579d5fdd37 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Tue, 31 Aug 2021 13:02:13 +0200 Subject: 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). --- conf/cf-lex.l | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- conf/confbase.Y | 11 ++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) (limited to 'conf') diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 704a1750..41520116 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] @@ -367,6 +369,61 @@ else: { . BUFFER_PUSH(quoted_buffer) = yytext[0]; +[b]["] { + BEGIN(BQUOTED); + quoted_buffer_init(); +} + +\n cf_error("Unterminated byte string"); +<> cf_error("Unterminated byte string"); +["] { + 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; +} + +. BUFFER_PUSH(quoted_buffer) = yytext[0]; + +[\\]({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); +} + +[\\][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(); +} + +\n cf_error("Unterminated base64 string"); +<> cf_error("Unterminated base64 string"); +["] { + 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; +} + +. BUFFER_PUSH(quoted_buffer) = yytext[0]; + <> { if (check_eof()) return END; } {WHITE}+ diff --git a/conf/confbase.Y b/conf/confbase.Y index 6985783b..99349c4e 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -92,7 +92,7 @@ CF_DECLS struct channel_limit cl; struct timeformat *tf; mpls_label_stack *mls; - struct bytestring *bs; + const struct bytestring *bs; } %token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT @@ -115,6 +115,7 @@ CF_DECLS %type label_stack_start label_stack %type text opttext +%type bytestring %type symbol %nonassoc PREFIX_DUMMY @@ -383,6 +384,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 -- cgit v1.2.3