summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authordenis <denis@cvs.openbsd.org>2018-06-11 09:39:59 +0000
committerdenis <denis@cvs.openbsd.org>2018-06-11 09:39:59 +0000
commit52359c977b99b54ea7b40b4664b6d61b133cb69d (patch)
tree9468eab1d8bb757e6f16704c885d68bf488ef912 /usr.sbin
parent64179aa8ab86f2cdbad2715504e3788eb720d741 (diff)
Fix an off-by-one line count when using include statements.
Thanks to otto@ for the initial diff. OK benno@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/iscsictl/parse.y106
1 files changed, 63 insertions, 43 deletions
diff --git a/usr.sbin/iscsictl/parse.y b/usr.sbin/iscsictl/parse.y
index c8b9377f165..4964afe3a0d 100644
--- a/usr.sbin/iscsictl/parse.y
+++ b/usr.sbin/iscsictl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.11 2018/04/26 14:12:19 krw Exp $ */
+/* $OpenBSD: parse.y,v 1.12 2018/06/11 09:39:58 denis Exp $ */
/*
* Copyright (c) 2010 David Gwynne <dlg@openbsd.org>
@@ -50,6 +50,10 @@ static struct file {
TAILQ_ENTRY(file) entry;
FILE *stream;
char *name;
+ size_t ungetpos;
+ size_t ungetsize;
+ u_char *ungetbuf;
+ int eof_reached;
int lineno;
int errors;
} *file, *topfile;
@@ -62,8 +66,9 @@ int yyerror(const char *, ...)
__attribute__((__nonnull__ (1)));
int kw_cmp(const void *, const void *);
int lookup(char *);
+int igetc(void);
int lgetc(int);
-int lungetc(int);
+void lungetc(int);
int findeol(void);
void clear_config(struct iscsi_config *);
@@ -393,34 +398,39 @@ lookup(char *s)
return (STRING);
}
-#define MAXPUSHBACK 128
+#define START_EXPAND 1
+#define DONE_EXPAND 2
-u_char *parsebuf;
-int parseindex;
-u_char pushback_buffer[MAXPUSHBACK];
-int pushback_index;
+static int expanding;
int
-lgetc(int quotec)
+igetc(void)
{
- int c, next;
+ int c;
- if (parsebuf) {
- /* Read character from the parsebuffer instead of input. */
- if (parseindex >= 0) {
- c = parsebuf[parseindex++];
- if (c != '\0')
- return (c);
- parsebuf = NULL;
- } else
- parseindex++;
+ while (1) {
+ if (file->ungetpos > 0)
+ c = file->ungetbuf[--file->ungetpos];
+ else
+ c = getc(file->stream);
+
+ if (c == START_EXPAND)
+ expanding = 1;
+ else if (c == DONE_EXPAND)
+ expanding = 0;
+ else
+ break;
}
+ return (c);
+}
- if (pushback_index)
- return (pushback_buffer[--pushback_index]);
+int
+lgetc(int quotec)
+{
+ int c, next;
if (quotec) {
- if ((c = getc(file->stream)) == EOF) {
+ if ((c = igetc()) == EOF) {
yyerror("reached end of file while parsing "
"quoted string");
if (file == topfile || popfile() == EOF)
@@ -430,8 +440,8 @@ lgetc(int quotec)
return (c);
}
- while ((c = getc(file->stream)) == '\\') {
- next = getc(file->stream);
+ while ((c = igetc()) == '\\') {
+ next = igetc();
if (next != '\n') {
c = next;
break;
@@ -448,20 +458,20 @@ lgetc(int quotec)
return (c);
}
-int
+void
lungetc(int c)
{
if (c == EOF)
- return (EOF);
- if (parsebuf) {
- parseindex--;
- if (parseindex >= 0)
- return (c);
+ return;
+
+ if (file->ungetpos >= file->ungetsize) {
+ void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
+ if (p == NULL)
+ err(1, "lungetc");
+ file->ungetbuf = p;
+ file->ungetsize *= 2;
}
- if (pushback_index < MAXPUSHBACK-1)
- return (pushback_buffer[pushback_index++] = c);
- else
- return (EOF);
+ file->ungetbuf[file->ungetpos++] = c;
}
int
@@ -469,14 +479,9 @@ findeol(void)
{
int c;
- parsebuf = NULL;
-
/* skip to either EOF or the first real EOL */
while (1) {
- if (pushback_index)
- c = pushback_buffer[--pushback_index];
- else
- c = lgetc(0);
+ c = lgetc(0);
if (c == '\n') {
file->lineno++;
break;
@@ -504,7 +509,7 @@ top:
if (c == '#')
while ((c = lgetc(0)) != '\n' && c != EOF)
; /* nothing */
- if (c == '$' && parsebuf == NULL) {
+ if (c == '$' && !expanding) {
while (1) {
if ((c = lgetc(0)) == EOF)
return (0);
@@ -526,8 +531,13 @@ top:
yyerror("macro '%s' not defined", buf);
return (findeol());
}
- parsebuf = val;
- parseindex = 0;
+ p = val + strlen(val) - 1;
+ lungetc(DONE_EXPAND);
+ while (p >= val) {
+ lungetc(*p);
+ p--;
+ }
+ lungetc(START_EXPAND);
goto top;
}
@@ -656,7 +666,16 @@ pushfile(const char *name, int secret)
free(nfile);
return (NULL);
}
- nfile->lineno = 1;
+ nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
+ nfile->ungetsize = 16;
+ nfile->ungetbuf = malloc(nfile->ungetsize);
+ if (nfile->ungetbuf == NULL) {
+ warn("malloc");
+ fclose(nfile->stream);
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
+ }
TAILQ_INSERT_TAIL(&files, nfile, entry);
return (nfile);
}
@@ -672,6 +691,7 @@ popfile(void)
TAILQ_REMOVE(&files, file, entry);
fclose(file->stream);
free(file->name);
+ free(file->ungetbuf);
free(file);
file = prev;
return (file ? 0 : EOF);