Tue Sep 21 21:03:36 2021 UTC ()
make: fix out-of-bounds memory read (since previous commit)


(rillig)
diff -r1.272 -r1.273 src/usr.bin/make/cond.c

cvs diff -r1.272 -r1.273 src/usr.bin/make/cond.c (expand / switch to unified diff)

--- src/usr.bin/make/cond.c 2021/09/21 20:54:42 1.272
+++ src/usr.bin/make/cond.c 2021/09/21 21:03:36 1.273
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cond.c,v 1.272 2021/09/21 20:54:42 rillig Exp $ */ 1/* $NetBSD: cond.c,v 1.273 2021/09/21 21:03:36 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -85,27 +85,27 @@ @@ -85,27 +85,27 @@
85 * Cond_restore_depth 85 * Cond_restore_depth
86 * Save and restore the nesting of the conditions, at 86 * Save and restore the nesting of the conditions, at
87 * the start and end of including another makefile, to 87 * the start and end of including another makefile, to
88 * ensure that in each makefile the conditional 88 * ensure that in each makefile the conditional
89 * directives are well-balanced. 89 * directives are well-balanced.
90 */ 90 */
91 91
92#include <errno.h> 92#include <errno.h>
93 93
94#include "make.h" 94#include "make.h"
95#include "dir.h" 95#include "dir.h"
96 96
97/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ 97/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
98MAKE_RCSID("$NetBSD: cond.c,v 1.272 2021/09/21 20:54:42 rillig Exp $"); 98MAKE_RCSID("$NetBSD: cond.c,v 1.273 2021/09/21 21:03:36 rillig Exp $");
99 99
100/* 100/*
101 * The parsing of conditional expressions is based on this grammar: 101 * The parsing of conditional expressions is based on this grammar:
102 * Or -> And 102 * Or -> And
103 * Or -> Or '||' And 103 * Or -> Or '||' And
104 * And -> Term 104 * And -> Term
105 * And -> And '&&' Term 105 * And -> And '&&' Term
106 * Term -> Function '(' Argument ')' 106 * Term -> Function '(' Argument ')'
107 * Term -> Leaf Operator Leaf 107 * Term -> Leaf Operator Leaf
108 * Term -> Leaf 108 * Term -> Leaf
109 * Term -> '(' Or ')' 109 * Term -> '(' Or ')'
110 * Term -> '!' Term 110 * Term -> '!' Term
111 * Leaf -> "string" 111 * Leaf -> "string"
@@ -784,30 +784,30 @@ CondParser_FuncCall(CondParser *par, boo @@ -784,30 +784,30 @@ CondParser_FuncCall(CondParser *par, boo
784 bool (*fn_eval)(size_t, const char *); 784 bool (*fn_eval)(size_t, const char *);
785 } fns[] = { 785 } fns[] = {
786 { "defined", 7, ParseFuncArg, FuncDefined }, 786 { "defined", 7, ParseFuncArg, FuncDefined },
787 { "make", 4, ParseFuncArg, FuncMake }, 787 { "make", 4, ParseFuncArg, FuncMake },
788 { "exists", 6, ParseFuncArg, FuncExists }, 788 { "exists", 6, ParseFuncArg, FuncExists },
789 { "empty", 5, ParseEmptyArg, FuncEmpty }, 789 { "empty", 5, ParseEmptyArg, FuncEmpty },
790 { "target", 6, ParseFuncArg, FuncTarget }, 790 { "target", 6, ParseFuncArg, FuncTarget },
791 { "commands", 8, ParseFuncArg, FuncCommands } 791 { "commands", 8, ParseFuncArg, FuncCommands }
792 }; 792 };
793 const struct fn_def *fn; 793 const struct fn_def *fn;
794 char *arg = NULL; 794 char *arg = NULL;
795 size_t arglen; 795 size_t arglen;
796 const char *cp = par->p; 796 const char *cp = par->p;
797 const struct fn_def *fns_end = fns + sizeof fns / sizeof fns[0]; 797 const struct fn_def *last_fn = fns + sizeof fns / sizeof fns[0] - 1;
798 798
799 for (fn = fns; !is_token(cp, fn->fn_name, fn->fn_name_len); fn++) 799 for (fn = fns; !is_token(cp, fn->fn_name, fn->fn_name_len); fn++)
800 if (fn == fns_end) 800 if (fn == last_fn)
801 return false; 801 return false;
802 802
803 cp += fn->fn_name_len; 803 cp += fn->fn_name_len;
804 cpp_skip_whitespace(&cp); 804 cpp_skip_whitespace(&cp);
805 if (*cp != '(') 805 if (*cp != '(')
806 return false; 806 return false;
807 807
808 arglen = fn->fn_parse(par, &cp, doEval, fn->fn_name, &arg); 808 arglen = fn->fn_parse(par, &cp, doEval, fn->fn_name, &arg);
809 if (arglen == 0 || arglen == (size_t)-1) { 809 if (arglen == 0 || arglen == (size_t)-1) {
810 par->p = cp; 810 par->p = cp;
811 *out_token = arglen == 0 ? TOK_FALSE : TOK_ERROR; 811 *out_token = arglen == 0 ? TOK_FALSE : TOK_ERROR;
812 return true; 812 return true;
813 } 813 }