Bug 10421 - hush does not terminate on hash (comment in last line of script string)
Summary: hush does not terminate on hash (comment in last line of script string)
Status: RESOLVED FIXED
Alias: None
Product: Busybox
Classification: Unclassified
Component: Other (show other bugs)
Version: unspecified
Hardware: All Linux
: P5 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-20 15:44 UTC by Julian Büning
Modified: 2017-10-22 13:57 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:


Attachments
suggested patch (784 bytes, patch)
2017-10-20 15:44 UTC, Julian Büning
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Julian Büning 2017-10-20 15:44:10 UTC
Created attachment 7286 [details]
suggested patch

Observed behavior:
$ ./busybox hush -c "#" &
[1] 1000
$ jobs
[1]+  Running                 ./busybox hush -c "#" &

Expected behavior:
$ ./busybox hush -c "#" &
[1] 1000
[1]+  Done                    ./busybox hush -c "#"

The same is true for a more elaborate example:

$ ./busybox hush -c "$(echo -en "echo foo # some comment\necho bar # some last words...")"
[no output, no termination]

When omitting the last comment, the command works as expected (outputting two lines, terminating).

We could reproduce this behavior using version 1.27.2 as well as the current master (commit 14c85eb) compiled with make defconfig && make.

The described behavior can be traced back to parse_stream() in hush.c:

>	/* skip "#comment" */
>	while (1) {
>    	ch = i_peek(input);
>		if (ch == EOF || ch == '\n')
>			break;
>		i_getch(input);
>		/* note: we do not add it to &ctx.as_string */
>	}

While i_getch() would return an EOF at the end of the argument string, i_peek() does not:

>	if (!i->file) {
>		/* string-based in_str */
>		/* Doesn't report EOF on NUL. None of the callers care. */
>		return (unsigned char)*i->p;
>	}

[ At least parse_stream() seems to care in this instance ]

To correct this behavior, we suggest to let i_peek() behave like i_getch() when encountering a 0-byte for string-based in_str (see attached patch).

This behavior was found using Symbolic Execution techniques developed in the course of the SYMBIOSYS research project at COMSYS, RWTH Aachen University. This research is supported by the European Research Council (ERC) under the EU's Horizon 2020 Research and Innovation Programme grant agreement n. 647295 (SYMBIOSYS).
Comment 1 Denys Vlasenko 2017-10-22 13:57:57 UTC
Thanks for the report!
Fixed in git.