Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syntax: the printer can split up strings when joined with escaped newlines #832

Closed
cilki opened this issue Mar 28, 2022 · 1 comment · Fixed by #837
Closed

syntax: the printer can split up strings when joined with escaped newlines #832

cilki opened this issue Mar 28, 2022 · 1 comment · Fixed by #837
Labels

Comments

@cilki
Copy link

cilki commented Mar 28, 2022

I came across this kind of assignment in a legacy codebase:

# Has the same effect as: wrapped='a b c'
wrapped=\
"a "\
"b "\
"c"

which shfmt turns into:

wrapped="a "\
	"b "\
	"c"

and causes the runtime error: line 4: b : command not found.

Tested on GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu) and the latest shfmt.

@mvdan
Copy link
Owner

mvdan commented Mar 28, 2022

Thanks, this does sound like a bug, probably in the printer. It should be taught to not indent after escaped newlines if that would change the program.

@mvdan mvdan changed the title cmd/shfmt breaks valid assignment statements syntax: the printer can split up strings when joined with escaped newlines Mar 28, 2022
@mvdan mvdan added the bug label Mar 29, 2022
mvdan added a commit that referenced this issue Apr 3, 2022
We did this in some cases involving simple literals,
but not in some others, such as two single-quoted literals joined with
an escaped newline.

The worst possible outcome is that formatting a program could break it.
For instance, the single statement below is equivalent to v=foobar:

	v='foo'\
	'bar'

however, we reformatted it to result in two commands due to indentation:

	v='foo'\
		'bar'

Instead, never keep escaped newlines in words if they aren't quoted.
They are still allowed when inside quotes, or when not part of a word.
Those are their main use cases, anyway, as we hadn't run into this
particularly buggy edge case yet.

Fixes #832.
@mvdan mvdan closed this as completed in #837 Apr 5, 2022
mvdan added a commit that referenced this issue Apr 5, 2022
We did this in some cases involving simple literals,
but not in some others, such as two single-quoted literals joined with
an escaped newline.

The worst possible outcome is that formatting a program could break it.
For instance, the single statement below is equivalent to v=foobar:

	v='foo'\
	'bar'

however, we reformatted it to result in two commands due to indentation:

	v='foo'\
		'bar'

Instead, never keep escaped newlines in words if they aren't quoted.
They are still allowed when inside quotes, or when not part of a word.
Those are their main use cases, anyway, as we hadn't run into this
particularly buggy edge case yet.

Fixes #832.
mvdan added a commit that referenced this issue Jul 3, 2022
As part of fixing #832, to prevent breaking some programs with escaped
newlines, I went slightly too far with the tightening of the rules.
The input script

	foo <<< \
		"bar baz"

would now reformat as

	foo <<< "\
	bar baz"

The script is functionally the same, but it looks objectively worse.
It is harmless to allow a leading escaped newline when not quoted,
as it doesn't break any programs nor result in worse formatting.

Note that the script

	foo=\
	bar

will still reformat as `foo=bar`, so in that case we keep the recent
change in behavior. That case is different, as we can't safely indent
the continuing line - thus we can't produce good formatting unless we
join the lines.

While here, remove incomplete code that I had left commented out in the
last patch, and then forgot to remove before merging.

Fixes #873.
mvdan added a commit that referenced this issue Jul 4, 2022
As part of fixing #832, to prevent breaking some programs with escaped
newlines, I went slightly too far with the tightening of the rules.
The input script

	foo <<< \
		"bar baz"

would now reformat as

	foo <<< "\
	bar baz"

The script is functionally the same, but it looks objectively worse.
It is harmless to allow a leading escaped newline when not quoted,
as it doesn't break any programs nor result in worse formatting.

Note that the script

	foo=\
	bar

will still reformat as `foo=bar`, so in that case we keep the recent
change in behavior. That case is different, as we can't safely indent
the continuing line - thus we can't produce good formatting unless we
join the lines.

While here, remove incomplete code that I had left commented out in the
last patch, and then forgot to remove before merging.

Fixes #873.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants