From: Mark Andrews Date: Wed, 25 Sep 2019 08:02:38 +0000 (+1000) Subject: Add support for parsing [=] X-Git-Tag: v9.17.18~34^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=42c22670b3970c0418acfbdc7645bf0e0368a750;p=thirdparty%2Fbind9.git Add support for parsing [=] where may be a quoted string. Previously quoted string only supported opening quotes at the start of the string. --- diff --git a/lib/isc/include/isc/lex.h b/lib/isc/include/isc/lex.h index fdbe10b92a8..84d4f424860 100644 --- a/lib/isc/include/isc/lex.h +++ b/lib/isc/include/isc/lex.h @@ -61,11 +61,11 @@ ISC_LANG_BEGINDECLS * Various options for isc_lex_gettoken(). */ -#define ISC_LEXOPT_EOL 0x01 /*%< Want end-of-line token. */ -#define ISC_LEXOPT_EOF 0x02 /*%< Want end-of-file token. */ -#define ISC_LEXOPT_INITIALWS 0x04 /*%< Want initial whitespace. */ -#define ISC_LEXOPT_NUMBER 0x08 /*%< Recognize numbers. */ -#define ISC_LEXOPT_QSTRING 0x10 /*%< Recognize qstrings. */ +#define ISC_LEXOPT_EOL 0x0001 /*%< Want end-of-line token. */ +#define ISC_LEXOPT_EOF 0x0002 /*%< Want end-of-file token. */ +#define ISC_LEXOPT_INITIALWS 0x0004 /*%< Want initial whitespace. */ +#define ISC_LEXOPT_NUMBER 0x0008 /*%< Recognize numbers. */ +#define ISC_LEXOPT_QSTRING 0x0010 /*%< Recognize qstrings. */ /*@}*/ /*@{*/ @@ -76,14 +76,16 @@ ISC_LANG_BEGINDECLS * the paren count is > 0. To use this option, '(' and ')' must be special * characters. */ -#define ISC_LEXOPT_DNSMULTILINE 0x20 /*%< Handle '(' and ')'. */ -#define ISC_LEXOPT_NOMORE 0x40 /*%< Want "no more" token. */ - -#define ISC_LEXOPT_CNUMBER 0x80 /*%< Recognize octal and hex. */ -#define ISC_LEXOPT_ESCAPE 0x100 /*%< Recognize escapes. */ -#define ISC_LEXOPT_QSTRINGMULTILINE 0x200 /*%< Allow multiline "" strings */ -#define ISC_LEXOPT_OCTAL 0x400 /*%< Expect a octal number. */ -#define ISC_LEXOPT_BTEXT 0x800 /*%< Bracketed text. */ +#define ISC_LEXOPT_DNSMULTILINE 0x0020 /*%< Handle '(' and ')'. */ +#define ISC_LEXOPT_NOMORE 0x0040 /*%< Want "no more" token. */ + +#define ISC_LEXOPT_CNUMBER 0x0080 /*%< Recognize octal and hex. */ +#define ISC_LEXOPT_ESCAPE 0x0100 /*%< Recognize escapes. */ +#define ISC_LEXOPT_QSTRINGMULTILINE 0x0200 /*%< Allow multiline "" strings */ +#define ISC_LEXOPT_OCTAL 0x0400 /*%< Expect a octal number. */ +#define ISC_LEXOPT_BTEXT 0x0800 /*%< Bracketed text. */ +#define ISC_LEXOPT_VPAIR 0x1000 /*%< Recognize value pair. */ +#define ISC_LEXOPT_QVPAIR 0x2000 /*%< Recognize quoted value pair. */ /*@}*/ /*@{*/ /*! @@ -117,7 +119,9 @@ typedef enum { isc_tokentype_initialws = 6, isc_tokentype_special = 7, isc_tokentype_nomore = 8, - isc_tokentype_btext = 8 + isc_tokentype_btext = 9, + isc_tokentype_vpair = 10, + isc_tokentype_qvpair = 11, } isc_tokentype_t; typedef union { diff --git a/lib/isc/lex.c b/lib/isc/lex.c index 3aef691694e..8ab36828739 100644 --- a/lib/isc/lex.c +++ b/lib/isc/lex.c @@ -293,7 +293,10 @@ typedef enum { lexstate_ccommentend, lexstate_eatline, lexstate_qstring, - lexstate_btext + lexstate_btext, + lexstate_vpair, + lexstate_vpairstart, + lexstate_qvpair, } lexstate; #define IWSEOL (ISC_LEXOPT_INITIALWS | ISC_LEXOPT_EOL) @@ -663,6 +666,29 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { remaining--; break; case lexstate_string: + if (!escaped && c == '=' && + (options & ISC_LEXOPT_VPAIR) != 0) { + INSIST(remaining > 0U); + *curr++ = c; + *curr = '\0'; + remaining--; + state = lexstate_vpairstart; + break; + } + /* FALLTHROUGH */ + case lexstate_vpairstart: + if (state == lexstate_vpairstart) { + if (c == '"' && + (options & ISC_LEXOPT_QVPAIR) != 0) { + INSIST(remaining > 0U); + no_comments = true; + state = lexstate_qvpair; + break; + } + state = lexstate_vpair; + } + /* FALLTHROUGH */ + case lexstate_vpair: /* * EOF needs to be checked before lex->specials[c] * as lex->specials[EOF] is not a good idea. @@ -676,7 +702,13 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { result = source->result; goto done; } - tokenp->type = isc_tokentype_string; + if (escaped && c == EOF) { + result = ISC_R_UNEXPECTEDEND; + goto done; + } + tokenp->type = (state == lexstate_string) + ? isc_tokentype_string + : isc_tokentype_vpair; tokenp->value.as_textregion.base = lex->data; tokenp->value.as_textregion.length = (unsigned int)(lex->max_token - @@ -753,6 +785,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { } break; case lexstate_qstring: + case lexstate_qvpair: if (c == EOF) { result = ISC_R_UNEXPECTEDEND; goto done; @@ -766,7 +799,10 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) { INSIST(prev != NULL); *prev = '"'; } else { - tokenp->type = isc_tokentype_qstring; + tokenp->type = + (state == lexstate_qstring) + ? isc_tokentype_qstring + : isc_tokentype_qvpair; tokenp->value.as_textregion.base = lex->data; tokenp->value.as_textregion.length = @@ -876,7 +912,12 @@ isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token, ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE; isc_result_t result; - if (expect == isc_tokentype_qstring) { + if (expect == isc_tokentype_vpair) { + options |= ISC_LEXOPT_VPAIR; + } else if (expect == isc_tokentype_qvpair) { + options |= ISC_LEXOPT_VPAIR; + options |= ISC_LEXOPT_QVPAIR; + } else if (expect == isc_tokentype_qstring) { options |= ISC_LEXOPT_QSTRING; } else if (expect == isc_tokentype_number) { options |= ISC_LEXOPT_NUMBER; @@ -895,7 +936,12 @@ isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token, return (ISC_R_SUCCESS); } if (token->type == isc_tokentype_string && - expect == isc_tokentype_qstring) { + (expect == isc_tokentype_qstring || expect == isc_tokentype_qvpair)) + { + return (ISC_R_SUCCESS); + } + if (token->type == isc_tokentype_vpair && + expect == isc_tokentype_qvpair) { return (ISC_R_SUCCESS); } if (token->type != expect) {