make(1): make parsing of the :gmtime and :localtime modifiers stricter
These variable modifiers accept an optional timestamp in seconds, to select which date to print. This feature is only used very rarely. The NetBSD build doesn't use it at all, and the FreeBSD build mainly uses the plain modifiers :gmtime and :localtime, but not their optional argument :gmtime=1500000000. Therefore, this change is not going to affect many builds. Those that are indeed affected had been wrong all the time anyway. At parse time, these errors stop the build, as intended. After that, when the actual shell commands of the targets are expanded and run, these errors don't stop anything, the build just continues as if nothing had happened. This is a general problem with Var_Parse, see the many "handle errors" markers in the code. Another problem is that on parse errors, parsing continues and spits out spurious strings of the form "mtime" and "ocaltime". This as well is a general problem with error handling in make. ok sjg
This commit is contained in:
parent
8ac215b8e4
commit
819ecf5275
|
@ -4,16 +4,24 @@ mod-gmtime:
|
||||||
%Y
|
%Y
|
||||||
localtime == localtime
|
localtime == localtime
|
||||||
mod-gmtime-indirect:
|
mod-gmtime-indirect:
|
||||||
make: Unknown modifier '1'
|
make: Invalid time value: ${:U1593536400}}
|
||||||
|
|
||||||
|
mtime=1593536400}
|
||||||
parse-errors:
|
parse-errors:
|
||||||
: -1 becomes Wed Dec 31 23:59:59 1969.
|
make: Invalid time value: -1}.
|
||||||
: space 1 becomes Thu Jan 1 00:00:01 1970.
|
|
||||||
|
: -1 becomes mtime=-1}.
|
||||||
|
make: Invalid time value: 1}.
|
||||||
|
|
||||||
|
: space 1 becomes mtime= 1}.
|
||||||
: 0 becomes ok.
|
: 0 becomes ok.
|
||||||
: 1 becomes Thu Jan 1 00:00:01 1970.
|
: 1 becomes Thu Jan 1 00:00:01 1970.
|
||||||
: INT32_MAX becomes Tue Jan 19 03:14:07 2038.
|
: INT32_MAX becomes Tue Jan 19 03:14:07 2038.
|
||||||
: INT32_MAX + 1 becomes Tue Jan 19 03:14:08 2038.
|
: INT32_MAX + 1 becomes Tue Jan 19 03:14:08 2038.
|
||||||
: overflow becomes Wed Dec 31 23:59:59 1969.
|
make: Invalid time value: 10000000000000000000000000000000}.
|
||||||
make: Unknown modifier 'e'
|
|
||||||
: letter becomes .
|
: overflow becomes mtime=10000000000000000000000000000000}.
|
||||||
|
make: Invalid time value: error}.
|
||||||
|
|
||||||
|
: letter becomes mtime=error}.
|
||||||
exit status 0
|
exit status 0
|
||||||
|
|
|
@ -4,16 +4,24 @@ mod-localtime
|
||||||
%Y
|
%Y
|
||||||
gmtime == gmtime
|
gmtime == gmtime
|
||||||
mod-localtime-indirect:
|
mod-localtime-indirect:
|
||||||
make: Unknown modifier '1'
|
make: Invalid time value: ${:U1593536400}}
|
||||||
|
|
||||||
|
ocaltime=1593536400}
|
||||||
parse-errors:
|
parse-errors:
|
||||||
: -1 becomes Thu Jan 1 00:59:59 1970.
|
make: Invalid time value: -1}.
|
||||||
: space 1 becomes Thu Jan 1 01:00:01 1970.
|
|
||||||
|
: -1 becomes ocaltime=-1}.
|
||||||
|
make: Invalid time value: 1}.
|
||||||
|
|
||||||
|
: space 1 becomes ocaltime= 1}.
|
||||||
: 0 becomes ok.
|
: 0 becomes ok.
|
||||||
: 1 becomes Thu Jan 1 01:00:01 1970.
|
: 1 becomes Thu Jan 1 01:00:01 1970.
|
||||||
: INT32_MAX becomes Tue Jan 19 04:14:07 2038.
|
: INT32_MAX becomes Tue Jan 19 04:14:07 2038.
|
||||||
: INT32_MAX + 1 becomes Tue Jan 19 04:14:08 2038.
|
: INT32_MAX + 1 becomes Tue Jan 19 04:14:08 2038.
|
||||||
: overflow becomes Thu Jan 1 00:59:59 1970.
|
make: Invalid time value: 10000000000000000000000000000000}.
|
||||||
make: Unknown modifier 'e'
|
|
||||||
: letter becomes .
|
: overflow becomes ocaltime=10000000000000000000000000000000}.
|
||||||
|
make: Invalid time value: error}.
|
||||||
|
|
||||||
|
: letter becomes ocaltime=error}.
|
||||||
exit status 0
|
exit status 0
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: var.c,v 1.630 2020/10/31 18:41:07 rillig Exp $ */
|
/* $NetBSD: var.c,v 1.631 2020/10/31 21:40:20 rillig Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1988, 1989, 1990, 1993
|
* Copyright (c) 1988, 1989, 1990, 1993
|
||||||
|
@ -119,6 +119,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -129,7 +130,7 @@
|
||||||
#include "metachar.h"
|
#include "metachar.h"
|
||||||
|
|
||||||
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
|
/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
|
||||||
MAKE_RCSID("$NetBSD: var.c,v 1.630 2020/10/31 18:41:07 rillig Exp $");
|
MAKE_RCSID("$NetBSD: var.c,v 1.631 2020/10/31 21:40:20 rillig Exp $");
|
||||||
|
|
||||||
#define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1)
|
#define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1)
|
||||||
#define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2)
|
#define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2)
|
||||||
|
@ -2113,6 +2114,24 @@ ApplyModifier_Literal(const char **pp, ApplyModifiersState *st)
|
||||||
return AMR_OK;
|
return AMR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Boolean TryParseTime(const char **pp, time_t *out_time)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
unsigned long n;
|
||||||
|
|
||||||
|
if (!ch_isdigit(**pp))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = strtoul(*pp, &end, 10);
|
||||||
|
if (n == ULONG_MAX && errno == ERANGE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*pp = end;
|
||||||
|
*out_time = (time_t)n; /* ignore possible truncation for now */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* :gmtime */
|
/* :gmtime */
|
||||||
static ApplyModifierResult
|
static ApplyModifierResult
|
||||||
ApplyModifier_Gmtime(const char **pp, ApplyModifiersState *st)
|
ApplyModifier_Gmtime(const char **pp, ApplyModifiersState *st)
|
||||||
|
@ -2124,9 +2143,12 @@ ApplyModifier_Gmtime(const char **pp, ApplyModifiersState *st)
|
||||||
return AMR_UNKNOWN;
|
return AMR_UNKNOWN;
|
||||||
|
|
||||||
if (mod[6] == '=') {
|
if (mod[6] == '=') {
|
||||||
char *ep;
|
const char *arg = mod + 7;
|
||||||
utc = (time_t)strtoul(mod + 7, &ep, 10);
|
if (!TryParseTime(&arg, &utc)) {
|
||||||
*pp = ep;
|
Parse_Error(PARSE_FATAL, "Invalid time value: %s\n", mod + 7);
|
||||||
|
return AMR_CLEANUP;
|
||||||
|
}
|
||||||
|
*pp = arg;
|
||||||
} else {
|
} else {
|
||||||
utc = 0;
|
utc = 0;
|
||||||
*pp = mod + 6;
|
*pp = mod + 6;
|
||||||
|
@ -2146,9 +2168,12 @@ ApplyModifier_Localtime(const char **pp, ApplyModifiersState *st)
|
||||||
return AMR_UNKNOWN;
|
return AMR_UNKNOWN;
|
||||||
|
|
||||||
if (mod[9] == '=') {
|
if (mod[9] == '=') {
|
||||||
char *ep;
|
const char *arg = mod + 10;
|
||||||
utc = (time_t)strtoul(mod + 10, &ep, 10);
|
if (!TryParseTime(&arg, &utc)) {
|
||||||
*pp = ep;
|
Parse_Error(PARSE_FATAL, "Invalid time value: %s\n", mod + 10);
|
||||||
|
return AMR_CLEANUP;
|
||||||
|
}
|
||||||
|
*pp = arg;
|
||||||
} else {
|
} else {
|
||||||
utc = 0;
|
utc = 0;
|
||||||
*pp = mod + 9;
|
*pp = mod + 9;
|
||||||
|
|
Loading…
Reference in New Issue