12671ee73SJamie Gritton %{ 22671ee73SJamie Gritton /*- 34d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 41de7b4b8SPedro F. Giffuni * 5d8352076SJamie Gritton * Copyright (c) 2011 James Gritton 62671ee73SJamie Gritton * All rights reserved. 72671ee73SJamie Gritton * 82671ee73SJamie Gritton * Redistribution and use in source and binary forms, with or without 92671ee73SJamie Gritton * modification, are permitted provided that the following conditions 102671ee73SJamie Gritton * are met: 112671ee73SJamie Gritton * 1. Redistributions of source code must retain the above copyright 122671ee73SJamie Gritton * notice, this list of conditions and the following disclaimer. 132671ee73SJamie Gritton * 2. Redistributions in binary form must reproduce the above copyright 142671ee73SJamie Gritton * notice, this list of conditions and the following disclaimer in the 152671ee73SJamie Gritton * documentation and/or other materials provided with the distribution. 162671ee73SJamie Gritton * 172671ee73SJamie Gritton * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 182671ee73SJamie Gritton * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 192671ee73SJamie Gritton * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 202671ee73SJamie Gritton * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 212671ee73SJamie Gritton * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 222671ee73SJamie Gritton * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 232671ee73SJamie Gritton * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 242671ee73SJamie Gritton * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 252671ee73SJamie Gritton * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 262671ee73SJamie Gritton * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 272671ee73SJamie Gritton * SUCH DAMAGE. 282671ee73SJamie Gritton */ 292671ee73SJamie Gritton 302671ee73SJamie Gritton #include <sys/cdefs.h> 312671ee73SJamie Gritton #include <err.h> 322671ee73SJamie Gritton #include <stddef.h> 332671ee73SJamie Gritton #include <stdlib.h> 342671ee73SJamie Gritton #include <string.h> 352671ee73SJamie Gritton 362671ee73SJamie Gritton #include "jailp.h" 372671ee73SJamie Gritton #include "y.tab.h" 382671ee73SJamie Gritton 39*086e0149SJamie Gritton #define YY_DECL int yylex(YYSTYPE *yylval, yyscan_t yyscanner) 40*086e0149SJamie Gritton #define YY_EXTRA_TYPE struct cflex* 412671ee73SJamie Gritton 42*086e0149SJamie Gritton extern YY_DECL; 43*086e0149SJamie Gritton 44*086e0149SJamie Gritton static ssize_t text2lval(size_t triml, size_t trimr, int tovar, 45*086e0149SJamie Gritton YYSTYPE *yylval, yyscan_t scanner); 462671ee73SJamie Gritton 472671ee73SJamie Gritton static int instr; 482671ee73SJamie Gritton %} 492671ee73SJamie Gritton 50a9a39d40SBaptiste Daroussin %option noyywrap 51a7880d59SJung-uk Kim %option noinput 52a7880d59SJung-uk Kim %option nounput 53*086e0149SJamie Gritton %option reentrant 54*086e0149SJamie Gritton %option yylineno 55a7880d59SJung-uk Kim 562671ee73SJamie Gritton %start _ DQ 572671ee73SJamie Gritton 582671ee73SJamie Gritton %% 592671ee73SJamie Gritton 602671ee73SJamie Gritton /* Whitespace or equivalent */ 61*086e0149SJamie Gritton <_>[ \t\r\n]+ instr = 0; 62*086e0149SJamie Gritton <_>#.* instr = 0; 63*086e0149SJamie Gritton <_>\/\/.* instr = 0; 64*086e0149SJamie Gritton <_>\/\*([^*]|(\*+([^*\/])))*\*+\/ instr = 0; 652671ee73SJamie Gritton 662671ee73SJamie Gritton /* Reserved tokens */ 672671ee73SJamie Gritton <_>\+= { 682671ee73SJamie Gritton instr = 0; 692671ee73SJamie Gritton return PLEQ; 702671ee73SJamie Gritton } 712671ee73SJamie Gritton <_>[,;={}] { 722671ee73SJamie Gritton instr = 0; 732671ee73SJamie Gritton return yytext[0]; 742671ee73SJamie Gritton } 752671ee73SJamie Gritton 762671ee73SJamie Gritton /* Atomic (unquoted) strings */ 772671ee73SJamie Gritton <_,DQ>[A-Za-z0-9_!%&()\-.:<>?@\[\]^`|~]+ | 782671ee73SJamie Gritton <_,DQ>\\(.|\n|[0-7]{1,3}|x[0-9A-Fa-f]{1,2}) | 792671ee73SJamie Gritton <_,DQ>[$*+/\\] { 80*086e0149SJamie Gritton (void)text2lval(0, 0, 0, yylval, yyscanner); 812671ee73SJamie Gritton return instr ? STR1 : (instr = 1, STR); 822671ee73SJamie Gritton } 832671ee73SJamie Gritton 842671ee73SJamie Gritton /* Single and double quoted strings */ 852671ee73SJamie Gritton <_>'([^\'\\]|\\(.|\n))*' { 86*086e0149SJamie Gritton (void)text2lval(1, 1, 0, yylval, yyscanner); 872671ee73SJamie Gritton return instr ? STR1 : (instr = 1, STR); 882671ee73SJamie Gritton } 892671ee73SJamie Gritton <_>\"([^"\\]|\\(.|\n))*\" | 902671ee73SJamie Gritton <DQ>[^\"$\\]([^"\\]|\\(.|\n))*\" { 912671ee73SJamie Gritton size_t skip; 922671ee73SJamie Gritton ssize_t atvar; 932671ee73SJamie Gritton 942671ee73SJamie Gritton skip = yytext[0] == '"' ? 1 : 0; 95*086e0149SJamie Gritton atvar = text2lval(skip, 1, 1, yylval, 96*086e0149SJamie Gritton yyscanner); 972671ee73SJamie Gritton if (atvar < 0) 982671ee73SJamie Gritton BEGIN _; 992671ee73SJamie Gritton else { 1002671ee73SJamie Gritton /* 1012671ee73SJamie Gritton * The string has a variable inside it. 1022671ee73SJamie Gritton * Go into DQ mode to get the variable 1032671ee73SJamie Gritton * and then the rest of the string. 1042671ee73SJamie Gritton */ 1052671ee73SJamie Gritton BEGIN DQ; 1062671ee73SJamie Gritton yyless(atvar); 1072671ee73SJamie Gritton } 1082671ee73SJamie Gritton return instr ? STR1 : (instr = 1, STR); 1092671ee73SJamie Gritton } 1102671ee73SJamie Gritton <DQ>\" BEGIN _; 1112671ee73SJamie Gritton 1122671ee73SJamie Gritton /* Variables, single-word or bracketed */ 1132671ee73SJamie Gritton <_,DQ>$[A-Za-z_][A-Za-z_0-9]* { 114*086e0149SJamie Gritton (void)text2lval(1, 0, 0, yylval, yyscanner); 1152671ee73SJamie Gritton return instr ? VAR1 : (instr = 1, VAR); 1162671ee73SJamie Gritton } 1172671ee73SJamie Gritton <_>$\{([^\n{}]|\\(.|\n))*\} | 1182671ee73SJamie Gritton <DQ>$\{([^\n\"{}]|\\(.|\n))*\} { 119*086e0149SJamie Gritton (void)text2lval(2, 1, 0, yylval, yyscanner); 1202671ee73SJamie Gritton return instr ? VAR1 : (instr = 1, VAR); 1212671ee73SJamie Gritton } 1222671ee73SJamie Gritton 1232671ee73SJamie Gritton /* Partially formed bits worth complaining about */ 1242671ee73SJamie Gritton <_>\/\*([^*]|(\*+([^*\/])))*\** { 1252671ee73SJamie Gritton warnx("%s line %d: unterminated comment", 126*086e0149SJamie Gritton yyextra->cfname, yylineno); 127*086e0149SJamie Gritton yyextra->error = 1; 1282671ee73SJamie Gritton } 1292671ee73SJamie Gritton <_>'([^\n'\\]|\\.)* | 1302671ee73SJamie Gritton <_>\"([^\n\"\\]|\\.)* { 1312671ee73SJamie Gritton warnx("%s line %d: unterminated string", 132*086e0149SJamie Gritton yyextra->cfname, yylineno); 133*086e0149SJamie Gritton yyextra->error = 1; 1342671ee73SJamie Gritton } 1352671ee73SJamie Gritton <_>$\{([^\n{}]|\\.)* | 1362671ee73SJamie Gritton <DQ>$\{([^\n\"{}]|\\.)* { 1372671ee73SJamie Gritton warnx("%s line %d: unterminated variable", 138*086e0149SJamie Gritton yyextra->cfname, yylineno); 139*086e0149SJamie Gritton yyextra->error = 1; 1402671ee73SJamie Gritton } 1412671ee73SJamie Gritton 1422671ee73SJamie Gritton /* A hack because "<0>" rules aren't allowed */ 1432671ee73SJamie Gritton <_>. return yytext[0]; 1442671ee73SJamie Gritton .|\n { 1452671ee73SJamie Gritton BEGIN _; 1462671ee73SJamie Gritton yyless(0); 1472671ee73SJamie Gritton } 1482671ee73SJamie Gritton 1492671ee73SJamie Gritton %% 1502671ee73SJamie Gritton 1512671ee73SJamie Gritton /* 1522671ee73SJamie Gritton * Copy string from yytext to yylval, handling backslash escapes, 1532671ee73SJamie Gritton * and optionally stopping at the beginning of a variable. 1542671ee73SJamie Gritton */ 1552671ee73SJamie Gritton static ssize_t 156*086e0149SJamie Gritton text2lval(size_t triml, size_t trimr, int tovar, YYSTYPE *yylval, 157*086e0149SJamie Gritton yyscan_t scanner) 1582671ee73SJamie Gritton { 1592671ee73SJamie Gritton char *d; 1602671ee73SJamie Gritton const char *s, *se; 1612671ee73SJamie Gritton 162*086e0149SJamie Gritton struct yyguts_t *yyg = scanner; 163*086e0149SJamie Gritton yylval->cs = d = emalloc(yyleng - trimr - triml + 1); 1642671ee73SJamie Gritton se = yytext + (yyleng - trimr); 1652671ee73SJamie Gritton for (s = yytext + triml; s < se; s++, d++) { 1662671ee73SJamie Gritton if (*s != '\\') { 1672671ee73SJamie Gritton if (tovar && *s == '$') { 1682671ee73SJamie Gritton *d = '\0'; 1692671ee73SJamie Gritton return s - yytext; 1702671ee73SJamie Gritton } 1712671ee73SJamie Gritton *d = *s; 1722671ee73SJamie Gritton continue; 1732671ee73SJamie Gritton } 1742671ee73SJamie Gritton s++; 1752671ee73SJamie Gritton if (*s >= '0' && *s <= '7') { 1762671ee73SJamie Gritton *d = *s - '0'; 1772671ee73SJamie Gritton if (s + 1 < se && s[1] >= '0' && s[1] <= '7') { 1782671ee73SJamie Gritton *d = 010 * *d + (*++s - '0'); 1792671ee73SJamie Gritton if (s + 1 < se && s[1] >= '0' && s[1] <= '7') 1802671ee73SJamie Gritton *d = 010 * *d + (*++s - '0'); 1812671ee73SJamie Gritton } 1822671ee73SJamie Gritton continue; 1832671ee73SJamie Gritton } 1842671ee73SJamie Gritton switch (*s) { 1852671ee73SJamie Gritton case 'a': *d = '\a'; break; 1862671ee73SJamie Gritton case 'b': *d = '\b'; break; 1872671ee73SJamie Gritton case 'f': *d = '\f'; break; 1882671ee73SJamie Gritton case 'n': *d = '\n'; break; 1892671ee73SJamie Gritton case 'r': *d = '\r'; break; 1902671ee73SJamie Gritton case 't': *d = '\t'; break; 1912671ee73SJamie Gritton case 'v': *d = '\v'; break; 1922671ee73SJamie Gritton default: *d = *s; break; 193*086e0149SJamie Gritton case '\n': d--; break; 1942671ee73SJamie Gritton case 'x': 1952671ee73SJamie Gritton *d = 0; 1962671ee73SJamie Gritton if (s + 1 >= se) 1972671ee73SJamie Gritton break; 1982671ee73SJamie Gritton if (s[1] >= '0' && s[1] <= '9') 1992671ee73SJamie Gritton *d = *++s - '0'; 2002671ee73SJamie Gritton else if (s[1] >= 'A' && s[1] <= 'F') 2012671ee73SJamie Gritton *d = *++s + (0xA - 'A'); 2026bd211bbSJamie Gritton else if (s[1] >= 'a' && s[1] <= 'f') 2032671ee73SJamie Gritton *d = *++s + (0xa - 'a'); 2042671ee73SJamie Gritton else 2052671ee73SJamie Gritton break; 2062671ee73SJamie Gritton if (s + 1 >= se) 2072671ee73SJamie Gritton break; 2082671ee73SJamie Gritton if (s[1] >= '0' && s[1] <= '9') 2092671ee73SJamie Gritton *d = *d * 0x10 + (*++s - '0'); 2102671ee73SJamie Gritton else if (s[1] >= 'A' && s[1] <= 'F') 2112671ee73SJamie Gritton *d = *d * 0x10 + (*++s + (0xA - 'A')); 212acf8ec56SJamie Gritton else if (s[1] >= 'a' && s[1] <= 'f') 2132671ee73SJamie Gritton *d = *d * 0x10 + (*++s + (0xa - 'a')); 2142671ee73SJamie Gritton } 2152671ee73SJamie Gritton } 2162671ee73SJamie Gritton *d = '\0'; 2172671ee73SJamie Gritton return -1; 2182671ee73SJamie Gritton } 219