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