GNU bug report logs - #63048
[Home] Shell alias values are not properly quoted

Previous Next

Package: guix;

Reported by: Ludovic Courtès <ludovic.courtes <at> inria.fr>

Date: Mon, 24 Apr 2023 07:58:01 UTC

Severity: normal

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 63048 in the body.
You can then email your comments to 63048 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to ekaitz <at> elenq.tech, bug-guix <at> gnu.org:
bug#63048; Package guix. (Mon, 24 Apr 2023 07:58:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Ludovic Courtès <ludovic.courtes <at> inria.fr>:
New bug report received and forwarded. Copy sent to ekaitz <at> elenq.tech, bug-guix <at> gnu.org. (Mon, 24 Apr 2023 07:58:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludovic.courtes <at> inria.fr>
To: bug-guix <at> gnu.org
Subject: [Home] Shell alias values are not properly quoted
Date: Mon, 24 Apr 2023 09:57:14 +0200
Hi!

As Ekaitz reported on Mastodon, shell alias values are not properly
quoted, which causes problem when an alias value contains double-quotes
for instance:

--8<---------------cut here---------------start------------->8---
(define (bash-serialize-aliases field-name val)
  #~(string-append
     #$@(map
         (match-lambda
           ((key . #f)
            "")
           ((key . #t)
            #~(string-append "alias " #$key "\n"))
           ((key . value)
            #~(string-append "alias " #$key "=\"" #$value "\"\n")))
         val)))
--8<---------------cut here---------------end--------------->8---

The solution is to borrow and factorize the code of
‘environment-variable-shell-definitions’, which does it right.

Ludo’.




Information forwarded to bug-guix <at> gnu.org:
bug#63048; Package guix. (Mon, 24 Apr 2023 10:11:01 GMT) Full text and rfc822 format available.

Message #8 received at 63048 <at> debbugs.gnu.org (full text, mbox):

From: Ekaitz Zarraga <ekaitz <at> elenq.tech>
To: Ludovic Courtès <ludovic.courtes <at> inria.fr>
Cc: 63048 <at> debbugs.gnu.org
Subject: Re: bug#63048: [Home] Shell alias values are not properly quoted
Date: Mon, 24 Apr 2023 10:10:29 +0000
As an extra note:

The problem I encountered was when the alias was defined using single quote marks:

alias ls='ls blabla "problem"'

this is parsed to:

("ls" . "blabla \"problem\"")

Which is written as:

alias ls="blabla "problem""

Which is wrong.

So the problem relies on the fact that the quotations marks have been changed from ' to " and the escaping have not been adjusted accordingly.

:)




Information forwarded to bug-guix <at> gnu.org:
bug#63048; Package guix. (Mon, 24 Apr 2023 17:42:02 GMT) Full text and rfc822 format available.

Message #11 received at 63048 <at> debbugs.gnu.org (full text, mbox):

From: Ekaitz Zarraga <ekaitz <at> elenq.tech>
To: Ludovic Courtès <ludovic.courtes <at> inria.fr>
Cc: 63048 <at> debbugs.gnu.org
Subject: Re: bug#63048: [Home] Shell alias values are not properly quoted
Date: Mon, 24 Apr 2023 17:41:08 +0000
I made something like this instead of reusing the code you suggested, Ludo.
But it doesn't work. I don't really know why:

diff --git a/guix/scripts/home/import.scm b/guix/scripts/home/import.scm
index fd263c0699..2d7a7abbf2 100644
--- a/guix/scripts/home/import.scm
+++ b/guix/scripts/home/import.scm
@@ -64,12 +64,23 @@ (define (destination-append path)
   (define alias-rx
     (make-regexp "^alias ([^=]+)=[\"'](.+)[\"']$"))
 
+  (define (quote-style line)
+    (cond
+      ((string-match "^alias ([^=]+)=[\"].*$" line) 'double)
+      ((string-match "^alias ([^=]+)=['].*$" line)  'single)))
+
   (define (bash-alias->pair line)
     (match (regexp-exec alias-rx line)
       (#f #f)
       (matched
        `(,(match:substring matched 1) . ,(match:substring matched 2)))))
 
+  (define (escape-alias-body quote-style body)
+    (if (eq? quote-style 'single)
+      (let* ((escaped-dquotes (string-replace-substring  body "\"" "\\\"")))
+        (string-replace-substring escaped-dquotes "\\'" "'"))
+      body))
+
   (define (parse-aliases input)
     (let loop ((result '()))
       (match (read-line input)
@@ -78,7 +89,7 @@ (define (parse-aliases input)
         (line
          (match (bash-alias->pair line)
            (#f    (loop result))
-           (alias (loop (cons alias result))))))))
+           (alias (loop (cons alias (escape-alias-body (quote-style line) result)))))))))
 
   (let ((rc (destination-append ".bashrc"))
         (profile (destination-append ".bash_profile"))





Information forwarded to , bug-guix <at> gnu.org:
bug#63048; Package guix. (Thu, 06 Jul 2023 15:03:01 GMT) Full text and rfc822 format available.

Message #14 received at 63048 <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 63048 <at> debbugs.gnu.org
Cc: Ludovic Courtès <ludovic.courtes <at> inria.fr>,
 Ekaitz Zarraga <ekaitz <at> elenq.tech>
Subject: [PATCH] home: services: bash: Properly quote shell aliases.
Date: Thu,  6 Jul 2023 17:01:54 +0200
From: Ludovic Courtès <ludovic.courtes <at> inria.fr>

Fixes <https://issues.guix.gnu.org/63048>.
Reported by Ekaitz Zarraga <ekaitz <at> elenq.tech>.

* gnu/home/services.scm (with-shell-quotation-bindings): New procedure.
(environment-variable-shell-definitions): Use it instead of inline copy.
* gnu/home/services/shells.scm (bash-serialize-aliases): Use it.  Add
clause for 'literal-string?'.
* tests/guix-home.sh: Add 'aliases' to 'home-bash-extension' and test it.
---
 gnu/home/services.scm        | 53 ++++++++++++++++++++----------------
 gnu/home/services/shells.scm | 28 ++++++++++++-------
 tests/guix-home.sh           |  7 ++++-
 3 files changed, 54 insertions(+), 34 deletions(-)

Hi!

Here's a patch that fixes it.  AFAICS 'guix home import' does the right
thing, so this is really just fixing the way aliases are serialized.

Let me know what you think!

Ludo'.

diff --git a/gnu/home/services.scm b/gnu/home/services.scm
index b17a34d19d..042eba4780 100644
--- a/gnu/home/services.scm
+++ b/gnu/home/services.scm
@@ -53,6 +53,7 @@ (define-module (gnu home services)
             literal-string?
             literal-string-value
 
+            with-shell-quotation-bindings
             environment-variable-shell-definitions
             home-files-directory
             xdg-configuration-files-directory
@@ -183,11 +184,10 @@ (define-record-type <literal-string>
   literal-string?
   (str literal-string-value))
 
-(define (environment-variable-shell-definitions variables)
-  "Return a gexp that evaluates to a list of POSIX shell statements defining
-VARIABLES, a list of environment variable name/value pairs.  The returned code
-ensures variable values are properly quoted."
-  #~(let* ((quote-string
+(define (with-shell-quotation-bindings exp)
+  "Insert EXP, a gexp, in a lexical environment providing the
+'shell-single-quote' and 'shell-double-quote' bindings."
+#~(let* ((quote-string
             (lambda (value quoted-chars)
               (list->string (string-fold-right
                              (lambda (chr lst)
@@ -206,24 +206,31 @@ (define (environment-variable-shell-definitions variables)
               ;; Single-quote VALUE to enter a literal string.
               (string-append "'" (quote-string value '(#\'))
                              "'"))))
-      (string-append
-       #$@(map (match-lambda
-                 ((key . #f)
-                  "")
-                 ((key . #t)
-                  #~(string-append "export " #$key "\n"))
-                 ((key . (or (? string? value)
-                             (? file-like? value)
-                             (? gexp? value)))
-                  #~(string-append "export " #$key "="
-                                   (shell-double-quote #$value)
-                                   "\n"))
-                 ((key . (? literal-string? value))
-                  #~(string-append "export " #$key "="
-                                   (shell-single-quote
-                                    #$(literal-string-value value))
-                                   "\n")))
-               variables))))
+      #$exp))
+
+(define (environment-variable-shell-definitions variables)
+  "Return a gexp that evaluates to a list of POSIX shell statements defining
+VARIABLES, a list of environment variable name/value pairs.  The returned code
+ensures variable values are properly quoted."
+  (with-shell-quotation-bindings
+   #~(string-append
+      #$@(map (match-lambda
+                ((key . #f)
+                 "")
+                ((key . #t)
+                 #~(string-append "export " #$key "\n"))
+                ((key . (or (? string? value)
+                            (? file-like? value)
+                            (? gexp? value)))
+                 #~(string-append "export " #$key "="
+                                  (shell-double-quote #$value)
+                                  "\n"))
+                ((key . (? literal-string? value))
+                 #~(string-append "export " #$key "="
+                                  (shell-single-quote
+                                   #$(literal-string-value value))
+                                  "\n")))
+              variables))))
 
 (define (environment-variables->setup-environment-script vars)
   "Return a file that can be sourced by a POSIX compliant shell which
diff --git a/gnu/home/services/shells.scm b/gnu/home/services/shells.scm
index 415b5470c5..7960590e7c 100644
--- a/gnu/home/services/shells.scm
+++ b/gnu/home/services/shells.scm
@@ -313,16 +313,24 @@ (define home-zsh-service-type
 ;;;
 
 (define (bash-serialize-aliases field-name val)
-  #~(string-append
-     #$@(map
-         (match-lambda
-           ((key . #f)
-            "")
-           ((key . #t)
-            #~(string-append "alias " #$key "\n"))
-           ((key . value)
-            #~(string-append "alias " #$key "=\"" #$value "\"\n")))
-         val)))
+  (with-shell-quotation-bindings
+   #~(string-append
+      #$@(map
+          (match-lambda
+            ((key . #f)
+             "")
+            ((key . #t)
+             #~(string-append "alias " #$key "\n"))
+            ((key . (? literal-string? value))
+             #~(string-append "alias " #$key "="
+                              (shell-single-quote
+                               #$(literal-string-value value))
+                              "\n"))
+            ((key . value)
+             #~(string-append "alias " #$key "="
+                              (shell-double-quote #$value)
+                              "\n")))
+          val))))
 
 (define-configuration home-bash-configuration
   (package
diff --git a/tests/guix-home.sh b/tests/guix-home.sh
index e9ef76c862..e6d16d7fab 100644
--- a/tests/guix-home.sh
+++ b/tests/guix-home.sh
@@ -1,7 +1,7 @@
 # GNU Guix --- Functional package management for GNU
 # Copyright © 2021-2023 Andrew Tropin <andrew <at> trop.in>
 # Copyright © 2021 Oleg Pykhalov <go.wigust <at> gmail.com>
-# Copyright © 2022 Ludovic Courtès <ludo <at> gnu.org>
+# Copyright © 2022, 2023 Ludovic Courtès <ludo <at> gnu.org>
 #
 # This file is part of GNU Guix.
 #
@@ -94,6 +94,9 @@ trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT
                    (home-bash-extension
                     (environment-variables
                       '(("PS1" . "$GUIX_ENVIRONMENT λ ")))
+                    (aliases
+                      `(("run" . "guix shell")
+                        ("path" . ,(literal-string "echo $PATH"))))
                     (bashrc
                      (list
                       (plain-file
@@ -149,6 +152,8 @@ EOF
     test -d "${HOME}/.guix-home"
     test -h "${HOME}/.bash_profile"
     test -h "${HOME}/.bashrc"
+    grep 'alias run="guix shell"' "$HOME/.bashrc"
+    grep "alias path='echo \$PATH'" "$HOME/.bashrc"
     test "$(tail -n 2 "${HOME}/.bashrc")" == "\
 # dot-bashrc test file for guix home
 # the content of bashrc-test-config.sh"

base-commit: 2426e51688d479042ea115a634c6be2d8b9f3b99
-- 
2.40.1





Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Tue, 11 Jul 2023 15:03:02 GMT) Full text and rfc822 format available.

Notification sent to Ludovic Courtès <ludovic.courtes <at> inria.fr>:
bug acknowledged by developer. (Tue, 11 Jul 2023 15:03:02 GMT) Full text and rfc822 format available.

Message #19 received at 63048-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: 63048-done <at> debbugs.gnu.org
Cc: paren <at> disroot.org, Ekaitz Zarraga <ekaitz <at> elenq.tech>,
 Andrew Tropin <andrew <at> trop.in>
Subject: Re: bug#63048: [Home] Shell alias values are not properly quoted
Date: Tue, 11 Jul 2023 17:02:34 +0200
Ludovic Courtès <ludo <at> gnu.org> skribis:

> From: Ludovic Courtès <ludovic.courtes <at> inria.fr>
>
> Fixes <https://issues.guix.gnu.org/63048>.
> Reported by Ekaitz Zarraga <ekaitz <at> elenq.tech>.
>
> * gnu/home/services.scm (with-shell-quotation-bindings): New procedure.
> (environment-variable-shell-definitions): Use it instead of inline copy.
> * gnu/home/services/shells.scm (bash-serialize-aliases): Use it.  Add
> clause for 'literal-string?'.
> * tests/guix-home.sh: Add 'aliases' to 'home-bash-extension' and test it.

Pushed as 7d9fdfb19d17dc99a4cf2548942c4f8ae7433572!

Ludo'.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 09 Aug 2023 11:24:09 GMT) Full text and rfc822 format available.

This bug report was last modified 254 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.