'wrap-script' introduces spurious argument

  • Open
  • quality assurance status badge
Details
6 participants
  • Attila Lendvai
  • Brendan Tildesley
  • Brendan Tildesley
  • Ludovic Courtès
  • Brendan Tildesley
  • Ricardo Wurmus
Owner
unassigned
Submitted by
Ludovic Courtès
Severity
normal
L
L
Ludovic Courtès wrote on 12 Mar 2020 15:26
(address . bug-Guix@gnu.org)
87k13psl82.fsf@inria.fr
Hello,

I have a script that starts with:

Toggle snippet (4 lines)
#!/gnu/store/29jhbbg1hf557x8j53f9sxd9imlmf02a-bash-minimal-5.0.7/bin/bash
#

When I call ‘wrap-script’ on it, it leads to:

Toggle snippet (8 lines)
#!/gnu/store/0awhym5h0m890n0wq87y0dxznh14rk88-guile-next-3.0.1/bin/guile --no-auto-compile
#!#; Guix wrapper
#\-(begin (setenv "PATH" "/gnu/store/9kzrrccpzl6i1sfwb0drb00gi2gwk0x0-coreutils-8.31/bin"))
#\-(let ((cl (command-line))) (apply execl "/gnu/store/29jhbbg1hf557x8j53f9sxd9imlmf02a-bash-minimal-5.0.7/bin/bash" (car cl) (cons (car cl) (append (quote ("")) cl))))
#!/gnu/store/29jhbbg1hf557x8j53f9sxd9imlmf02a-bash-minimal-5.0.7/bin/bash
#

The expression (append '("") cl) is incorrect: the empty string
shouldn’t be added here.

I think one way to fix it is:
Toggle diff (14 lines)
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index b8be73ead4..f9698773c3 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -1295,7 +1295,8 @@ not supported."
(car cl)
(cons (car cl)
(append
- ',(string-split args #\space)
+ ',(string-tokenize args
+ char-set:graphic)
cl))))))
(template (string-append prog ".XXXXXX"))
(out (mkstemp! template))
Ludo’.
B
B
Brendan Tildesley wrote on 22 Mar 2020 01:53
(address . 40039@debbugs.gnu.org)
2969f516-ca88-ffa6-dd65-f6a29682d42c@gmail.com
It appears the repeated (car cl) results in the executable path getting
sent to it's self as the first argument. I'm not sure how things managed
to work up until now? I tested the following change and it fixed the one
case I was using, but am not sure it is correct. why was the cons (car
cl) there in the first place?


Toggle diff (33 lines)
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index b8be73ead4..9610f39d71 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -946,7 +946,7 @@ FILE are kept unchanged."
                                                   "patch-shebang: ~a:
changing `~a' to `~a'~%"
                                                   file (string-append
interp " " arg1) bin)
                                           (patch p bin rest))
-                                      (begin
+                                      (begin
                                         (format (current-error-port)
                                                 "patch-shebang: ~a:
changing `~a' to `~a'~%"
                                                 file interp bin)
@@ -1292,11 +1292,10 @@ not supported."
                                                        (_ vars))))
                                    `(let ((cl (command-line)))
                                       (apply execl ,interpreter
-                                             (car cl)
-                                             (cons (car cl)
-                                                   (append
- ',(string-split args #\space)
-                                                    cl))))))
+                                             (car cl) ;; The program.
+                                             (append
+                                              ',(string-tokenize args
#\space)
+                                              cl)))))
                    (template (string-append prog ".XXXXXX"))
                    (out      (mkstemp! template))
                    (st       (stat prog))
R
R
Ricardo Wurmus wrote on 22 Mar 2020 11:27
Re: bug#40039: 'wrap-script' introduces spurious argument
(name . Brendan Tildesley)(address . brendan.tildesley@gmail.com)(address . 40039@debbugs.gnu.org)
87pnd4lm5p.fsf@elephly.net
Brendan Tildesley <brendan.tildesley@gmail.com> writes:

Toggle quote (6 lines)
> It appears the repeated (car cl) results in the executable path
> getting sent to it's self as the first argument. I'm not sure how
> things managed to work up until now? I tested the following change and
> it fixed the one case I was using, but am not sure it is correct. why
> was the cons (car cl) there in the first place?

See the documentation of execl:

-- Scheme Procedure: execl filename arg ...
-- C Function: scm_execl (filename, args)
Executes the file named by FILENAME as a new process image. The
remaining arguments are supplied to the process; from a C program
they are accessible as the ‘argv’ argument to ‘main’.
Conventionally the first ARG is the same as FILENAME. All
arguments must be strings.

If ARG is missing, FILENAME is executed with a null argument list,
which may have system-dependent side-effects.

This procedure is currently implemented using the ‘execv’ system
call, but we call it ‘execl’ because of its Scheme calling
interface.

--
Ricardo
B
B
Brendan Tildesley wrote on 22 Mar 2020 12:42
(name . Ricardo Wurmus)(address . rekado@elephly.net)
da7aaff2-7d12-ed30-d9b4-3b9f5bd37357@brendan.scot
I'm currently packaging libratbag which provides the cli interface
ratbagctl. when launched without arguments, it normally the current devices

######################
## with wrap-program (correct):
b@ui ~/guix [env]$ ratbagctl
warbling-mara:       Logitech G102 Prodigy Gaming Mouse

b@ui ~/guix [env]$ head `which ratbagctl`
#!/gnu/store/29jhbbg1hf557x8j53f9sxd9imlmf02a-bash-minimal-5.0.7/bin/bash
export
PYTHONPATH="/gnu/store/88v8lvs02sdqgzv7w96g19fvh8hffzzp-libratbag-0.13/lib/python3.7/site-packages/:/gnu/store/h4jkr0qg86zjn1kq6iq8v33pcadj9r13-python-evdev-1.3.0/lib/python3.7/site-packages/:/gnu/store/z5fdc5aa9hs4c3p79ajzgxhazv7702y8-python-pygobject-3.28.3/lib/python3.7/site-packages/"
exec -a "$0"
"/gnu/store/88v8lvs02sdqgzv7w96g19fvh8hffzzp-libratbag-0.13/bin/.ratbagctl-real"
"$@"


######################
## with wrap-script:
b@ui ~/guix [env]$ ratbagctl
usage: /gnu/store/754ylqjs68va7rswr3fscwa0kyazsbjq-profile/bin/ratbagctl
<device>
       {info,name,profile,resolution,dpi,rate,button,led} ...
/gnu/store/754ylqjs68va7rswr3fscwa0kyazsbjq-profile/bin/ratbagctl
<device>: error: invalid choice:
'/gnu/store/754ylqjs68va7rswr3fscwa0kyazsbjq-profile/bin/ratbagctl'
(choose from 'info', 'name', 'profile', 'resolution', 'dpi', 'rate',
'button', 'led')

b@ui ~/guix [env]$ ratbagctl list
/gnu/store/754ylqjs68va7rswr3fscwa0kyazsbjq-profile/bin/ratbagctl
<device>: error: invalid choice:
'/gnu/store/754ylqjs68va7rswr3fscwa0kyazsbjq-profile/bin/ratbagctl'
(choose from 'info', 'name', 'profile', 'resolution', 'dpi', 'rate',
'button', 'led')
b@ui ~/guix [env]$ ratbagctl info rastkasnts atkatkaf ftbaontb
aesbtabtowf ~5qawylftarsnvbawlpfyq
usage: /gnu/store/754ylqjs68va7rswr3fscwa0kyazsbjq-profile/bin/ratbagctl
<device>
       {info,name,profile,resolution,dpi,rate,button,led} ...
/gnu/store/754ylqjs68va7rswr3fscwa0kyazsbjq-profile/bin/ratbagctl
<device>: error: invalid choice:
'/gnu/store/754ylqjs68va7rswr3fscwa0kyazsbjq-profile/bin/ratbagctl'
(choose from 'info', 'name', 'profile', 'resolution', 'dpi', 'rate',
'button', 'led')
b@ui ~/guix [env]$

b@ui ~/guix [env]$ head `which ratbagctl`
#!/gnu/store/0awhym5h0m890n0wq87y0dxznh14rk88-guile-next-3.0.1/bin/guile
--no-auto-compile
#!#; Guix wrapper
#\-(begin (setenv "PYTHONPATH"
"/gnu/store/1hcpppqc6268siki64vs1ygq1qsr8w35-libratbag-0.13/lib/python3.7/site-packages/:/gnu/store/h4jkr0qg86zjn1kq6iq8v33pcadj9r13-python-evdev-1.3.0/lib/python3.7/site-packages/:/gnu/store/z5fdc5aa9hs4c3p79ajzgxhazv7702y8-python-pygobject-3.28.3/lib/python3.7/site-packages/"))
#\-(let ((cl (command-line))) (apply execl
"/gnu/store/608bvypsh90c58apvd2cgg3m9l2pwjqn-python-3.7.4/bin/python3"
(car cl) (cons (car cl) (append (quote ("")) cl))))
#!/gnu/store/608bvypsh90c58apvd2cgg3m9l2pwjqn-python-3.7.4/bin/python3

####################

Here I make a copy of the guix build utils module and modify the
wrap-script, removing #\space as suggested, so it defaults to
char-set:graphic. This results in the above guile wrapper chaging to:

#\-(let ((cl (command-line))) (apply execl
"/gnu/store/608bvypsh90c58apvd2cgg3m9l2pwjqn-python-3.7.4/bin/python3"
(car cl) (cons (car cl) (append (quote ()) cl))))

The behaviour changes somewhat. Now running ratbagctl prints the
commants list, which is what should happen when the wrong arguments are
provided, e.g., `ratbagctl qwfqwfqf`


b@ui ~/guix [env]$ ratbagctl
usage: ratbagctl [OPTIONS] list
       ratbagctl [OPTIONS] <device> {COMMAND} ...


b@ui ~/guix [env]$ ratbagctl list
usage: /gnu/store/fgl1w0lh1pzqg8j4gi8j1yi29aa122ja-profile/bin/ratbagctl
<device>
       {info,name,profile,resolution,dpi,rate,button,led} ...
/gnu/store/fgl1w0lh1pzqg8j4gi8j1yi29aa122ja-profile/bin/ratbagctl
<device>: error: invalid choice: 'list' (choose from 'info', 'name',
'profile', 'resolution', 'dpi', 'rate', 'button', 'led')
B
B
Brendan Tildesley wrote on 13 Sep 2020 04:35
(address . 40039@debbugs.gnu.org)
3489a6d8-59fb-3452-4220-0936b76caae2@gmail.com
Hi Ricardo, Ludovic... I was wondering if we could revisit and fix this.
I believe there is more than 1 bug here.

Suppose we have the script test.sh

#!/run/current-system/profile/bin/bash
echo "$@"

./test.sh returns:

hi

Wrapping with wrap-script returns

 ./test.sh hi

(notice the extract space at the start.)

With Ludovic's change to char-set:graphicY

.test.sh hi

The leading space is gone at least. Finally, after removing one of the
(car cl)'s, if finally just returns hi.
Attachment: file
R
R
Ricardo Wurmus wrote on 13 Sep 2020 14:23
(name . Brendan Tildesley)(address . brendan.tildesley@gmail.com)
87pn6pzwzn.fsf@elephly.net
Brendan Tildesley <brendan.tildesley@gmail.com> writes:

Toggle quote (3 lines)
> Hi Ricardo, Ludovic... I was wondering if we could revisit and fix
> this.

Yes, let’s try to fix this. I think it would be good to have a bunch of
automated tests that we can work with to validate the feature even in
somewhat obscure circumstances.

It’s been a while since I originally wrote the code, so some decisions
are no longer obvious to me, but I’ll try to familiarize myself with it
once again.

--
Ricardo
B
B
Brendan Tildesley wrote on 29 Apr 2021 17:23
'wrap-script' introduces spurious argument
(name . 40039@debbugs.gnu.org)(address . 40039@debbugs.gnu.org)
964865602.98225.1619709804547@office.mailbox.org
Same patch as before, but with a test case. Have a play with it and see if it makes sense.
Attachment: file
A
A
Attila Lendvai wrote on 9 Sep 2021 21:02
(No Subject)
(name . 40039@debbugs.gnu.org)(address . 40039@debbugs.gnu.org)
17aao-2MRYlPVbMhh6TI3GVeht_ewLvkBD4MB9OJpuWQQf-OOa8zJRTZuzOAugdQ9MvutN5CEDq0TwDpcoHSgtTzaV5iy-HWIN9aoTLZVbg=@lendvai.name
any ETA on this fix? i think i need it.

i tried to add a `wrap-script-or-program` to `python-build-system`: attempt to use `wrap-scipt`, and in case of a `no-interpreter-found` error fall back to `wrap-program`. (motivated by trezor-agent relying on sys.argv[0], which is ruined by `wrap-program`)

the result of my change was that building `serf` dies, and i suspect that because of this bug.

the output:

command "scons" "-j" "8" "APR=/gnu/store/gxq63qb00yn11vv875n7l9fffs2gmgxp-apr-1.6.5" "APU=/gnu/store/gl2wzkld26ry7xainbbbwgrz493925xn-apr-util-1.6.1" "OPENSSL=/gnu/store/ixm51m1jcfw4rhvwnd690szfv2w3pcsm-openssl-1.1.1j" "ZLIB=/gnu/store/rykm237xkmq7rl1p0nwass01p090p88x-zlib-1.2.11" "PREFIX=/gnu/store/pgs8b7410lap9ax68wbq2j5kyhhb3kwf-serf-1.3.9" failed with status 127

note that after my change `scons` is wrapped as a script, not as a program.

i tried to apply this fix, and retry, but it seems to cause the rebuilding of the entire world -- and i'm on a laptop... :)

so, i think i'll just wait until this fix reaches main, and i'll retry after that.

- attila
PGP: 5D5F 45C7 DFCD 0A39
Attachment: file
?