Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Suggestion: Option to ignore unmatched quotes when (Q) parameter-expansion flag

dg1727 wrote on Wed, Apr 13, 2022 at 21:12:13 +0000:
> If variable ${u_input} contains the user's input, we start with
> something equivalent to:
> a_string='one[abc]two'
> if [[ "${a_string}" == ${u_input} ]] then
>   print "it matches"  # Now it matches!
> fi
> *** The current problem is the shell's handling of unbalanced
> quotation marks:
> a_string='one[abc]"two'  # unbalanced doublequote
> u_input='*[abc]"*'
> # the user tries to match that doublequote and the [], all 3 literally
> u_input="${(Q)${(b)u_input}}"
> # u_input is now \*\[abc\]"\*
> # the (Q) was skipped
> If we add the (X) flag to make (QX) so the shell will print an error
> message, we find that the shell detects the unbalanced (").
> The zshexpn documentation for X says "Without the [X] flag, errors are
> silently ignored."  It seems that, without (X), the unbalanced (")
> isn't 'ignored,' but rather causes the (Q) flag to fail entirely.
> *** I looked at the source code a little bit, and I have the following
> suggestion, whose details are NOT terribly firm:
> Manpage zshexpn, section Parameter Expansion Flags:
>   change last sentence of description of X to:
>   Without the flag, errors silently cause the current processing step to be skipped.
> Add to the description of Q flag:
>   Handling of unbalanced quotes depends on whether the X flag is
>   present.
>   Also, if the Q flag is given twice and the X flag is *not* given,
>   then unbalanced quotation marks are silently ignored; other forms of
>   quoting are still removed.  (For example, if a string contains an
>   unbalanced double-quote but the outermost level of quoting within
>   the string includes balanced single-quotes, then the single-quotes
>   will be removed.)

A couple of points:

- Wrap your lines to 80 columns.  It's hard to read otherwise.

- It's premature to go to this level of implementation details at this
  point in the discussion.  More precisely, it can cause tunnel vision.
  We should consider all possible implementations of the proposed
  functinality, and all possible functionalities that may address the
  original use-case.

- The best way to show proposed changes is by posting a unidiff (the
  output of `git diff`, attached in a file named *.txt).  That's true
  even if the changes are alpha quality or even not meant to be applied
  at all.

- I don't know that it makes sense to tie your program's glob syntax to
  zsh's input syntax (as opposed to zsh's pattern syntax, which is what
  plain «[[ $foo == $bar ]]» does).  The fact that it's hard to
  implement is a clue in and of itself.  You're essentially inventing
  your own string matching library here.

- Now, if you actually wanted to use zsh's _input_ syntax, the obvious
  idea would be to use «eval» — but it's not trivial to implement that
  in a way that doesn't risk bobby tables bugs (e.g., if the pattern
  is «& pwd»).

- Couldn't you simply append a «"» character to the user input and then
  use zsh unmodified?  (You'd have to try three times: with no append,
  with an appended «"», with an appended «'».)



> Many thanks for your time.
> -dg1727

Messages sorted by: Reverse Date, Date, Thread, Author