Opened 11 years ago

Closed 11 years ago

#1012 closed defect (fixed)

getopt-long discards doublequotes and option values after whitespace characters

Reported by: evhan Owned by: Ivan Raikov
Priority: minor Milestone: someday
Component: extensions Version: 4.8.x
Keywords: getopt-long Cc:
Estimated difficulty:

Description

getopt-long contains logic for handling doublequote-wrapped option values. However, this interferes with option values containing internal doublequotes and makes it impossible to pass arguments that explicitly include surrounding doublequotes. I believe argument quoting is adequately resolved by the shell before option values are ever in CHICKEN's control (i.e. in the command-line-arguments parameter), so this logic is unnecessary and the attached patch removes it.

getopt-long also discards any characters in option values after and including the first whitespace character (that is, those in srfi-14's char-set:blank). This makes it impossible to pass arguments containing spaces without intentionally double-quoting them (to activate the doublequote-handling logic, which I believe is incorrect as noted above).

Finally, getopt-long accepts only a small set of characters in option values, raising an error on any characters not in that set. I believe this is an unnecessary restriction, so the patch removes it as well.

;;
;; Given the following (and assuming a common shell):
;;

(pp (command-line-arguments))
(pp (getopt-long (command-line-arguments) '((foo (value #t)))))

;;
;; $ ./test --foo="\"bar\""
;; ("--foo=\"bar\"")
;; ((@) (foo . "bar"))
;;
;; $ ./test --foo="bar baz qux"
;; ("--foo=bar baz qux")
;; ((@) (foo . "bar"))
;;
;; $ ./test --foo="\"bar baz qux\""
;; ("--foo=\"bar baz qux\"")
;; ((@) (foo . "bar baz qux"))
;;
;; $ ./test --foo="\"bar baz\" qux"                                                                                 
;; ("--foo=\"bar baz\" qux")
;; ((@) (foo . "bar baz"))
;;
;; $ ./test --foo='bar"baz"qux'
;; ("--foo=bar\"baz\"qux")
;; ((@) (foo . "barbazqux"))
;;
;; $ ./test --foo='bar+baz=qux'
;; ("--foo=bar+baz=qux")
;; Error: (long-option-value) invalid option character: #\+
;;

Attachments (1)

simplify-long-option-value-handling.patch (2.1 KB) - added by evhan 11 years ago.

Download all attachments as: .zip

Change History (3)

Changed 11 years ago by evhan

comment:1 Changed 11 years ago by Ivan Raikov

Owner: set to Ivan Raikov
Status: newaccepted

Hello,

Thanks for using getopt-long and providing the patch. I have updated getopt-long to address your issues by making the quote escaping functionality optional, and by making the long option value character set configurable. While you are correct that bash and modern Unix shells do the right thing with regard to quoting, I am not so sure this the case for Windows, so for now I will preserve and make optional the getopt-long quotation mechanism. I also agree with your point about white space in option values. I have changed the getopt-long procedure to take an optional keyword value, 'long-option-value-cset', which specifies an SRFI-14 char set with the valid characters allowed in option values. This character set defaults to letters, numbers, punctuation, and spaces, but you can extend it further if this is not enough. Please try the new version and let me know if you need further changes. Thanks.

comment:2 Changed 11 years ago by evhan

Resolution: fixed
Status: acceptedclosed

Hi Ivan,

This is perfect -- thank you for the consideration and quick fix, it's very appreciated.

Closing.

Note: See TracTickets for help on using tickets.