[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#973852: Debootstrap with mirror_style 'main' fails



On Fri, 6 Nov 2020 at 13:20, Tim Connors <tim.connors@ranchosoquel.net> wrote:

Hi, I haven't time to read the actual code, but your explanation of
your fix seems incorrect.

I suggest you write some simple test code like I show below,
to confirm what is actually occurring.

Be sure to test in the correct shell (ie probably not bash).

> at line 911.  The cause is line 885 in the same function
>
>      for p in "$@"; do
>
> The double quotes cause the list of packages to be seen as a
> single item.

No, in that statement, they don't. $@ behaves like an array.
Its elements are separate items. As shown:

[david@kablamm ~]$ dash
$ set 1 2 3 4 5
$ printf '%s\n' "$@"
1
2
3
4
5
$ for e in "$@" ; do printf '%s\n' "$e" ; done
1
2
3
4
5
$

> The for loop iterates only once with the value of p containing
> the entire space-separated list of packages.

Incorrect, see above.

> The fix is to remove the double quotes.  I've have tried this fix and
> it works.

It might "work" by some kind of luck, but it is unlikely to
be the correct fix.

Double quotes around "$@" will prevent globbing and
word-splitting of each element inside $@.

Removing double quotes is dangerous because it
enables globbing which can lead to unpredictable
bugs depending on the unpredictable interaction  of
whatever filenames are present in the current directory
interacting with unexpected globbing behaviour of any
shell metacharacters contained in $@.
It is generally dangerous bad practice and difficult to debug.

> The bug was introduced when line 425 in 1.0.89
>
>      "$DOWNLOAD_DEBS" $(echo "$@" | tr ' ' '\n' | sort)
>
> was replaced with (at line 484 in 1.0.114)
>
>      "$DOWNLOAD_DEBS" "$(echo "$@" | tr ' ' '\n' | sort)"

It will be these added quotes that cause all the text output by
the 'sort' pipeline to to be treated as a single item by the
DOWNLOAD_DEBS command. I demonstrate this below.

This coding approach is poor because it starts with
data in an _array_ and converts it into a _string_.
Because $@ is an array, and the output of $(....)
is a string.

Converting to a string loses the separation of arguments,
and the old code relied on word-splitting to separate them.
Adding the double quotes broke that. That is what needs
to be fixed.

Without knowing what is inside the "$@" passed to the
'echo' command, I don't know exactly what is occurring,
but it might be something like this:

$ set "1 1" "2          2"
$ echo $@
1 1 2 2
$ echo "$@"
1 1 2          2

Note the whitespace between the two 2 characters
is lost, due to word-splitting.

That leads to this
(where printf shows what DOWNLOAD_DEBS gets for
its argument values, note they are extremely different):
$ set "1 1" "2          2"
$ printf '%s\n' $(echo "$@")
1
1
2
2
$ printf '%s\n' "$(echo "$@")"
1 1 2          2
$

This might also help understanding:
  https://github.com/koalaman/shellcheck/wiki/SC2046
  https://github.com/koalaman/shellcheck/wiki/SC2068

Good luck and I hope this results in better code for
the project, cheers.


Reply to: