xref: /freebsd/contrib/bmake/unit-tests/opt-file.mk (revision a0ca4af9455b844c5e094fc1b09b1390ffa979fc)
1# $NetBSD: opt-file.mk,v 1.16 2024/04/01 12:26:02 rillig Exp $
2#
3# Tests for the -f command line option, which adds a makefile to the list of
4# files that are parsed.
5
6# TODO: Implementation
7
8all: .PHONY
9all: file-ending-in-backslash
10all: file-ending-in-backslash-mmap
11all: line-with-trailing-whitespace
12all: file-containing-null-byte
13
14# When the filename is '-', the input comes from stdin.  This is unusual but
15# possible.
16#
17# In the unlikely case where a file ends in a backslash instead of a newline,
18# that backslash is trimmed.  See ReadLowLevelLine.
19#
20# make-2014.01.01.00.00.00 invoked undefined behavior, reading text from
21# outside of the file buffer.
22#
23#	printf '%s' 'VAR=value\' \
24#	| MALLOC_OPTIONS="JA" \
25#	  MALLOC_CONF="junk:true" \
26#	  make-2014.01.01.00.00.00 -r -f - -V VAR -dA 2>&1 \
27#	| less
28#
29# The debug output shows how make happily uses freshly allocated memory (the
30# <A5>) and already freed memory ('Z').
31#
32#	ParseReadLine (1): 'VAR=value\<A5><A5><A5><A5><A5><A5>'
33#	Global:VAR = value\<A5><A5><A5><A5><A5><A5>value\<A5><A5><A5><A5><A5><A5>
34#	ParseReadLine (2): 'alue\<A5><A5><A5><A5><A5><A5>'
35#	ParseDependency(alue\<A5><A5><A5><A5><A5><A5>)
36#	make-2014.01.01.00.00.00: "(stdin)" line 2: Need an operator
37#	ParseReadLine (3): '<A5><A5><A5>ZZZZZZZZZZZZZZZZ'
38#	ParseDependency(<A5><A5><A5>ZZZZZZZZZZZZZZZZ)
39#
40file-ending-in-backslash: .PHONY
41	@printf '%s' 'VAR=value\' \
42	| ${MAKE} -r -f - -V VAR
43
44# Between parse.c 1.170 from 2010-12-25 and parse.c 1.511 from 2020-12-22,
45# there was an out-of-bounds write in ParseGetLine, where line_end pointed at
46# the end of the allocated buffer, in the special case where loadedfile_mmap
47# had not added the final newline character.
48file-ending-in-backslash-mmap: .PHONY
49	@printf '%s' 'VAR=value\' > opt-file-backslash
50	@${MAKE} -r -f opt-file-backslash -V VAR
51	@rm opt-file-backslash
52
53# Since parse.c 1.511 from 2020-12-22, an assertion in ParseGetLine failed
54# for lines that contained trailing whitespace.  Worked around in parse.c
55# 1.513, properly fixed in parse.c 1.514 from 2020-12-22.
56line-with-trailing-whitespace: .PHONY
57	@printf '%s' 'VAR=$@ ' > opt-file-trailing-whitespace
58	@${MAKE} -r -f opt-file-trailing-whitespace -V VAR
59	@rm opt-file-trailing-whitespace
60
61# If a makefile contains null bytes, it is an error.  Throughout the history
62# of make, the behavior has changed several times, sometimes intentionally,
63# sometimes by accident.
64#
65#	echo 'VAR=value' | tr 'l' '\0' > zero-byte.in
66#	printf '%s\n' 'all:' ': VAR=${VAR:Q}' >> zero-byte.in
67#
68#	for year in $(seq 2003 2020); do
69#	  echo $year:
70#	  make-$year.01.01.00.00.00 -r -f zero-byte.in
71#	  echo "exit status $?"
72#	  echo
73#	done 2>&1 \
74#	| sed "s,$PWD/,.,"
75#
76# This program generated the following output:
77#
78#	2003 to 2007:
79#	exit status 0
80#
81#	2008 to 2010:
82#	make: "(stdin)" line 1: Zero byte read from file
83#	make: Fatal errors encountered -- cannot continue
84#
85#	make: stopped in .
86#	exit status 1
87#
88#	2011 to 2013:
89#	make: no target to make.
90#
91#	make: stopped in .
92#	exit status 2
93#
94#	2014 to 2020-12-06:
95#	make: "(stdin)" line 1: warning: Zero byte read from file, skipping rest of line.
96#	exit status 0
97#
98#	Since 2020-12-07:
99#	make: "(stdin)" line 1: Zero byte read from file
100#	make: Fatal errors encountered -- cannot continue
101#	make: stopped in .
102#	exit status 1
103#
104#	Since 2024-04-01:
105#	make: "(stdin)" line 1: Zero byte read from file
106#	*** Error code 2 (continuing)
107file-containing-null-byte: .PHONY
108	@printf '%s\n' 'VAR=value' 'VAR2=VALUE2' \
109	| tr 'l' '\0' \
110	| ${MAKE} -r -f - -V VAR -V VAR2
111
112all:
113	: Making ${.TARGET}
114