Module Name: src Committed By: rillig Date: Sun Aug 22 11:57:23 UTC 2021
Modified Files: src/usr.bin/xlint/lint2: read.c Log Message: lint: extract parse_tspec from inptype Add error handling for unknown type character, which led to read of uninitialized memory before. No practical change as far as lint2 only ever reads output from lint1, since that is well-formed. To generate a diff of this commit: cvs rdiff -u -r1.49 -r1.50 src/usr.bin/xlint/lint2/read.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/xlint/lint2/read.c diff -u src/usr.bin/xlint/lint2/read.c:1.49 src/usr.bin/xlint/lint2/read.c:1.50 --- src/usr.bin/xlint/lint2/read.c:1.49 Sun Aug 8 11:56:35 2021 +++ src/usr.bin/xlint/lint2/read.c Sun Aug 22 11:57:23 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.49 2021/08/08 11:56:35 rillig Exp $ */ +/* $NetBSD: read.c,v 1.50 2021/08/22 11:57:23 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: read.c,v 1.49 2021/08/08 11:56:35 rillig Exp $"); +__RCSID("$NetBSD: read.c,v 1.50 2021/08/22 11:57:23 rillig Exp $"); #endif #include <ctype.h> @@ -556,13 +556,70 @@ usedsym(pos_t *posp, const char *cp) hte->h_lusym = &usym->u_next; } +static tspec_t +parse_tspec(const char **pp, char c, bool *osdef) +{ + char s; + + switch (c) { + case 's': /* 'signed' or 'struct' or 'float' */ + case 'u': /* 'unsigned' or 'union' */ + case 'l': /* 'long double' */ + case 'e': /* 'enum' */ + s = c; + c = *(*pp)++; + break; + default: + s = '\0'; + break; + } + + switch (c) { + case 'B': + return BOOL; + case 'C': + return s == 's' ? SCHAR : (s == 'u' ? UCHAR : CHAR); + case 'S': + return s == 'u' ? USHORT : SHORT; + case 'I': + return s == 'u' ? UINT : INT; + case 'L': + return s == 'u' ? ULONG : LONG; + case 'Q': + return s == 'u' ? UQUAD : QUAD; +#ifdef INT128_SIZE + case 'J': + return s == 'u' ? UINT128 : INT128; +#endif + case 'D': + return s == 's' ? FLOAT : (s == 'l' ? LDOUBLE : DOUBLE); + case 'V': + return VOID; + case 'P': + return PTR; + case 'A': + return ARRAY; + case 'F': + case 'f': + *osdef = c == 'f'; + return FUNC; + case 'T': + return s == 'e' ? ENUM : (s == 's' ? STRUCT : UNION); + case 'X': + return s == 's' ? FCOMPLEX + : (s == 'l' ? LCOMPLEX : DCOMPLEX); + default: + inperr("tspec '%c'", c); + } +} + /* * Read a type and return the index of this type. */ static u_short inptype(const char *cp, const char **epp) { - char c, s; + char c; const char *ep; type_t *tp; int narg, i; @@ -595,68 +652,7 @@ inptype(const char *cp, const char **epp c = *cp++; } - switch (c) { - case 's': - case 'u': - case 'l': - case 'e': - s = c; - c = *cp++; - break; - default: - s = '\0'; - break; - } - - switch (c) { - case 'B': - tp->t_tspec = BOOL; - break; - case 'C': - tp->t_tspec = s == 's' ? SCHAR : (s == 'u' ? UCHAR : CHAR); - break; - case 'S': - tp->t_tspec = s == 'u' ? USHORT : SHORT; - break; - case 'I': - tp->t_tspec = s == 'u' ? UINT : INT; - break; - case 'L': - tp->t_tspec = s == 'u' ? ULONG : LONG; - break; - case 'Q': - tp->t_tspec = s == 'u' ? UQUAD : QUAD; - break; -#ifdef INT128_SIZE - case 'J': - tp->t_tspec = s == 'u' ? UINT128 : INT128; - break; -#endif - case 'D': - tp->t_tspec = s == 's' ? FLOAT : (s == 'l' ? LDOUBLE : DOUBLE); - break; - case 'V': - tp->t_tspec = VOID; - break; - case 'P': - tp->t_tspec = PTR; - break; - case 'A': - tp->t_tspec = ARRAY; - break; - case 'F': - case 'f': - osdef = c == 'f'; - tp->t_tspec = FUNC; - break; - case 'T': - tp->t_tspec = s == 'e' ? ENUM : (s == 's' ? STRUCT : UNION); - break; - case 'X': - tp->t_tspec = s == 's' ? FCOMPLEX - : (s == 'l' ? LCOMPLEX : DCOMPLEX); - break; - } + tp->t_tspec = parse_tspec(&cp, c, &osdef); switch (tp->t_tspec) { case ARRAY: