]> granicus.if.org Git - sudo/commitdiff
Split tokenizer utility functions out into toke_util.c
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 7 Feb 2011 15:29:34 +0000 (10:29 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 7 Feb 2011 15:29:34 +0000 (10:29 -0500)
--HG--
branch : 1.7

Makefile.in
toke.h [new file with mode: 0644]
toke.l
toke_util.c [new file with mode: 0644]

index 4d985d898d5ac57ef0c246b01e0e2ba48f205be0..aec42400d3c65482bf611cbaffb61553aa74c16d 100644 (file)
@@ -113,8 +113,8 @@ SRCS = aix.c alias.c alloc.c audit.c boottime.c bsm_audit.c check.c \
        pwutil.c set_perms.c setsid.c sigaction.c snprintf.c strcasecmp.c \
        strerror.c strlcat.c strlcpy.c strsignal.c sudo.c sudo_noexec.c \
        sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c toke.c toke.l \
-       tsgetgrpw.c utimes.c vasgroups.c visudo.c zero_bytes.c redblack.c \
-       selinux.c sesh.c sudoreplay.c getdate.c getdate.y getline.c \
+       toke_util.c tsgetgrpw.c utimes.c vasgroups.c visudo.c zero_bytes.c \
+       redblack.c selinux.c sesh.c sudoreplay.c getdate.c getdate.y getline.c \
        timestr.c $(AUTH_SRCS)
 
 AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
@@ -125,14 +125,14 @@ AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
 HDRS = alloc.h bsm_audit.h def_data.h defaults.h error.h ins_2001.h \
        ins_classic.h ins_csops.h ins_goons.h insults.h interfaces.h lbuf.h \
        linux_audit.h list.h logging.h missing.h mksiglist.h nonunix.h \
-       redblack.h parse.h sudo.h sudo_exec.h sudo_nss.h gram.h \
+       redblack.h parse.h sudo.h sudo_exec.h sudo_nss.h gram.h toke.h \
        auth/sudo_auth.h emul/charclass.h emul/fnmatch.h emul/glob.h \
        emul/timespec.h emul/utime.h
 
 AUTH_OBJS = sudo_auth.o @AUTH_OBJS@
 
 COMMON_OBJS = alias.o alloc.o defaults.o error.o gram.o \
-             list.o match.o pwutil.o timestr.o toke.o redblack.o \
+             list.o match.o pwutil.o timestr.o toke.o toke_util.o redblack.o \
              term.o zero_bytes.o @COMMON_OBJS@
 
 SUDO_OBJS = $(AUTH_OBJS) @SUDO_OBJS@ audit.o boottime.o check.o env.o \
@@ -390,8 +390,10 @@ tgetpass.o: $(srcdir)/tgetpass.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tgetpass.c
 timestr.o: $(srcdir)/timestr.c $(srcdir)/missing.h config.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/timestr.c
-toke.o: $(devdir)/toke.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
+toke.o: $(devdir)/toke.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/toke.h $(devdir)/gram.h
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(devdir)/toke.c
+toke_util.o: $(devdir)/toke_util.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/toke.h $(devdir)/gram.h
+       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(devdir)/toke_util.c
 tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(SUDODEP)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tsgetgrpw.c
 utimes.o: $(srcdir)/utimes.c $(srcdir)/missing.h $(srcdir)/emul/utime.h config.h
diff --git a/toke.h b/toke.h
new file mode 100644 (file)
index 0000000..6200826
--- /dev/null
+++ b/toke.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SUDO_TOKE_H
+#define _SUDO_TOKE_H
+
+int append(char *, int);
+int fill_args(char *, int, int);
+int fill_cmnd(char *, int);
+int fill_txt(char *, int, int);
+int ipv6_valid(const char *s);
+void yyerror(const char *);
+
+/* realloc() to size + COMMANDARGINC to make room for command args */
+#define COMMANDARGINC   64
+
+#endif /* _SUDO_TOKE_H */
diff --git a/toke.l b/toke.l
index 9a475bc4e8f71fa6a0ce03de51634a6218f96cbf..1c12452351fba71f2a13ba757aea18c57c797801 100644 (file)
--- a/toke.l
+++ b/toke.l
@@ -68,6 +68,7 @@
 #include <ctype.h>
 #include "sudo.h"
 #include "parse.h"
+#include "toke.h"
 #include <gram.h>
 
 extern YYSTYPE yylval;
@@ -76,27 +77,16 @@ int sudolineno = 1;
 char *sudoers;
 static int sawspace = 0;
 static int prev_state = INITIAL;
-static int arg_len = 0;
-static int arg_size = 0;
 
-static int append              __P((char *, int));
-static int _fill               __P((char *, int, int));
-static int fill_cmnd           __P((char *, int));
-static int fill_args           __P((char *, int, int));
 static int _push_include       __P((char *, int));
 static int pop_include         __P((void));
-static int ipv6_valid          __P((const char *s));
 static char *parse_include     __P((char *));
-extern void yyerror            __P((const char *));
 
-#define fill(a, b)             _fill(a, b, 0)
+#define fill(a, b)             fill_txt(a, b, 0)
 
 #define        push_include(_p)        (_push_include((_p), FALSE))
 #define        push_includedir(_p)     (_push_include((_p), TRUE))
 
-/* realloc() to size + COMMANDARGINC to make room for command args */
-#define COMMANDARGINC  64
-
 #ifdef TRACELEXER
 #define LEXTRACE(msg)  fputs(msg, stderr)
 #else
@@ -561,177 +551,6 @@ sudoedit          {
                        }
 
 %%
-static unsigned char
-hexchar(s)
-    const char *s;
-{
-    int i;
-    int result = 0;
-
-    s += 2; /* skip \\x */
-    for (i = 0; i < 2; i++) {
-       switch (*s) {
-       case 'A':
-       case 'a':
-           result += 10;
-           break;
-       case 'B':
-       case 'b':
-           result += 11;
-           break;
-       case 'C':
-       case 'c':
-           result += 12;
-           break;
-       case 'D':
-       case 'd':
-           result += 13;
-           break;
-       case 'E':
-       case 'e':
-           result += 14;
-           break;
-       case 'F':
-       case 'f':
-           result += 15;
-           break;
-       default:
-           result += *s - '0';
-           break;
-       }
-       if (i == 0) {
-           result *= 16;
-           s++;
-       }
-    }
-    return (unsigned char)result;
-}
-
-static int
-_fill(src, len, olen)
-    char *src;
-    int len, olen;
-{
-    char *dst;
-
-    dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
-    if (dst == NULL) {
-       yyerror("unable to allocate memory");
-       return FALSE;
-    }
-    yylval.string = dst;
-
-    /* Copy the string and collapse any escaped characters. */
-    dst += olen;
-    while (len--) {
-       if (*src == '\\' && len) {
-           if (src[1] == 'x' && len >= 3 && 
-               isxdigit((unsigned char) src[2]) &&
-               isxdigit((unsigned char) src[3])) {
-               *dst++ = hexchar(src);
-               src += 4;
-               len -= 3;
-           } else {
-               src++;
-               len--;
-               *dst++ = *src++;
-           }
-       } else {
-           *dst++ = *src++;
-       }
-    }
-    *dst = '\0';
-    return TRUE;
-}
-
-static int
-append(src, len)
-    char *src;
-    int len;
-{
-    int olen = 0;
-
-    if (yylval.string != NULL)
-       olen = strlen(yylval.string);
-
-    return _fill(src, len, olen);
-}
-
-#define SPECIAL(c) \
-    ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
-
-static int
-fill_cmnd(src, len)
-    char *src;
-    int len;
-{
-    char *dst;
-    int i;
-
-    arg_len = arg_size = 0;
-
-    dst = yylval.command.cmnd = (char *) malloc(len + 1);
-    if (yylval.command.cmnd == NULL) {
-       yyerror("unable to allocate memory");
-       return FALSE;
-    }
-
-    /* Copy the string and collapse any escaped sudo-specific characters. */
-    for (i = 0; i < len; i++) {
-       if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
-           *dst++ = src[++i];
-       else
-           *dst++ = src[i];
-    }
-    *dst = '\0';
-
-    yylval.command.args = NULL;
-    return TRUE;
-}
-
-static int
-fill_args(s, len, addspace)
-    char *s;
-    int len;
-    int addspace;
-{
-    int new_len;
-    char *p;
-
-    if (yylval.command.args == NULL) {
-       addspace = 0;
-       new_len = len;
-    } else
-       new_len = arg_len + len + addspace;
-
-    if (new_len >= arg_size) {
-       /* Allocate more space than we need for subsequent args */
-       while (new_len >= (arg_size += COMMANDARGINC))
-           ;
-
-       p = yylval.command.args ?
-           (char *) realloc(yylval.command.args, arg_size) :
-           (char *) malloc(arg_size);
-       if (p == NULL) {
-           efree(yylval.command.args);
-           yyerror("unable to allocate memory");
-           return FALSE;
-       } else
-           yylval.command.args = p;
-    }
-
-    /* Efficiently append the arg (with a leading space if needed). */
-    p = yylval.command.args + arg_len;
-    if (addspace)
-       *p++ = ' ';
-    if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
-       yyerror("fill_args: buffer overflow");  /* paranoia */
-       return FALSE;
-    }
-    arg_len = new_len;
-    return TRUE;
-}
-
 struct path_list {
     char *path;
     struct path_list *next;
@@ -1022,26 +841,3 @@ parse_include(base)
 
     return path;
 }
-
-/*
- * Check to make sure an IPv6 address does not contain multiple instances
- * of the string "::".  Assumes strlen(s) >= 1.
- * Returns TRUE if address is valid else FALSE.
- */
-static int
-ipv6_valid(s)
-    const char *s;
-{
-    int nmatch = 0;
-
-    for (; *s != '\0'; s++) {
-       if (s[0] == ':' && s[1] == ':') {
-           if (++nmatch > 1)
-               break;
-       }
-       if (s[0] == '/')
-           nmatch = 0;                 /* reset if we hit netmask */
-    }
-
-    return nmatch <= 1;
-}
diff --git a/toke_util.c b/toke_util.c
new file mode 100644 (file)
index 0000000..99e7552
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2011
+ *     Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#include <ctype.h>
+#include "sudo.h"
+#include "parse.h"
+#include "toke.h"
+#include <gram.h>
+
+static int arg_len = 0;
+static int arg_size = 0;
+
+static unsigned char
+hexchar(s)
+    const char *s;
+{
+    int i;
+    int result = 0;
+
+    s += 2; /* skip \\x */
+    for (i = 0; i < 2; i++) {
+       switch (*s) {
+       case 'A':
+       case 'a':
+           result += 10;
+           break;
+       case 'B':
+       case 'b':
+           result += 11;
+           break;
+       case 'C':
+       case 'c':
+           result += 12;
+           break;
+       case 'D':
+       case 'd':
+           result += 13;
+           break;
+       case 'E':
+       case 'e':
+           result += 14;
+           break;
+       case 'F':
+       case 'f':
+           result += 15;
+           break;
+       default:
+           result += *s - '0';
+           break;
+       }
+       if (i == 0) {
+           result *= 16;
+           s++;
+       }
+    }
+    return (unsigned char)result;
+}
+
+int
+fill_txt(src, len, olen)
+    char *src;
+    int len, olen;
+{
+    char *dst;
+
+    dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
+    if (dst == NULL) {
+       yyerror("unable to allocate memory");
+       return FALSE;
+    }
+    yylval.string = dst;
+
+    /* Copy the string and collapse any escaped characters. */
+    dst += olen;
+    while (len--) {
+       if (*src == '\\' && len) {
+           if (src[1] == 'x' && len >= 3 && 
+               isxdigit((unsigned char) src[2]) &&
+               isxdigit((unsigned char) src[3])) {
+               *dst++ = hexchar(src);
+               src += 4;
+               len -= 3;
+           } else {
+               src++;
+               len--;
+               *dst++ = *src++;
+           }
+       } else {
+           *dst++ = *src++;
+       }
+    }
+    *dst = '\0';
+    return TRUE;
+}
+
+int
+append(src, len)
+    char *src;
+    int len;
+{
+    int olen = 0;
+
+    if (yylval.string != NULL)
+       olen = strlen(yylval.string);
+
+    return fill_txt(src, len, olen);
+}
+
+#define SPECIAL(c) \
+    ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
+
+int
+fill_cmnd(src, len)
+    char *src;
+    int len;
+{
+    char *dst;
+    int i;
+
+    arg_len = arg_size = 0;
+
+    dst = yylval.command.cmnd = (char *) malloc(len + 1);
+    if (yylval.command.cmnd == NULL) {
+       yyerror("unable to allocate memory");
+       return FALSE;
+    }
+
+    /* Copy the string and collapse any escaped sudo-specific characters. */
+    for (i = 0; i < len; i++) {
+       if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
+           *dst++ = src[++i];
+       else
+           *dst++ = src[i];
+    }
+    *dst = '\0';
+
+    yylval.command.args = NULL;
+    return TRUE;
+}
+
+int
+fill_args(s, len, addspace)
+    char *s;
+    int len;
+    int addspace;
+{
+    int new_len;
+    char *p;
+
+    if (yylval.command.args == NULL) {
+       addspace = 0;
+       new_len = len;
+    } else
+       new_len = arg_len + len + addspace;
+
+    if (new_len >= arg_size) {
+       /* Allocate more space than we need for subsequent args */
+       while (new_len >= (arg_size += COMMANDARGINC))
+           ;
+
+       p = yylval.command.args ?
+           (char *) realloc(yylval.command.args, arg_size) :
+           (char *) malloc(arg_size);
+       if (p == NULL) {
+           efree(yylval.command.args);
+           yyerror("unable to allocate memory");
+           return FALSE;
+       } else
+           yylval.command.args = p;
+    }
+
+    /* Efficiently append the arg (with a leading space if needed). */
+    p = yylval.command.args + arg_len;
+    if (addspace)
+       *p++ = ' ';
+    if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
+       yyerror("fill_args: buffer overflow");  /* paranoia */
+       return FALSE;
+    }
+    arg_len = new_len;
+    return TRUE;
+}
+
+/*
+ * Check to make sure an IPv6 address does not contain multiple instances
+ * of the string "::".  Assumes strlen(s) >= 1.
+ * Returns TRUE if address is valid else FALSE.
+ */
+int
+ipv6_valid(s)
+    const char *s;
+{
+    int nmatch = 0;
+
+    for (; *s != '\0'; s++) {
+       if (s[0] == ':' && s[1] == ':') {
+           if (++nmatch > 1)
+               break;
+       }
+       if (s[0] == '/')
+           nmatch = 0;                 /* reset if we hit netmask */
+    }
+
+    return nmatch <= 1;
+}