-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix handling of odd strings by test
builtin
#3581
fix handling of odd strings by test
builtin
#3581
Conversation
The existing code is inconsistent, and in a couple of cases wrong, about dealing with strings that are not valid ints. For example, there are locations that call wcstol() and check errno without first setting errno to zero. Normalize the code to a consistent pattern. This does make some syntax more liberal. For example `echo $PATH[1 .. 3]` is now valid due to uniformly allowing leading and trailing whitespace around numbers. Whereas prior to this change you would get a "Invalid index value" error. Contrast this with `echo $PATH[ 1.. 3 ]` which was valid and still is.
The `test` builtin currently has unexpected behavior with respect to expressions such as `'' -eq 0`. That currently evaluates to true with a return status of zero. This change addresses that oddity while also ensuring that other unusual strings (e.g., numbers with leading and trailing whitespace) are handled consistently. Fixes #3346
@ridiculousfish: I think the only part of this that needs a quick look from you is my use of |
Also, this fixes issue #3346. I'll update the commit comment to mention that when I merge it. |
I haven't tried this PR yet - there are conflicts. Does this let |
Sort of. Fish now fails the test but does not emit a diagnostic. Note that even without this change doing something nonsensical like |
👍 Though, beware all - a number of our scripts end up relying on the no-error fish e.g. - test "$VTE_VERSION" -lt 4000
+ test "0$VTE_VERSION" -lt 4000 |
(Or, you could just redirect stderr to |
Ugh! Adding a diagnostic causes test failures because the unit tests either assume an empty string is equivalent to "0" or don't suppress errors. I'm still going to add the error message because it's the right thing to do, and fix the unit tests. However, this does make me worry that there are a not insignificant number of scripts that depend on the current, silent, behavior. |
And unfortunately What would probably be a nice thing to do given potential pain from new errors in random scripts people may suffer after a change like this, would be to improve our error output to make identifying where a I had something along the lines of this happening locally at one point, but can't find the commit. $ [ $foobar -gt 1 ]
[: Non-numeric argument at index 0: ‘’
[: given args: ‘’, ‘-gt‘, ‘1‘, ‘]‘ Such improvements should be a handled in different issue. |
See issue #2860 that I opened eight months ago to pointing out that all diagnostic messages need to provide more context. There are too many issues of that type that need to be a high priority to resolve. Not sure how to get attention focused on those issues. |
static bool parse_number(const wcstring &arg, long long *out) { | ||
*out = fish_wcstoll(arg.c_str()); | ||
if (errno) { | ||
debug(0, "test: invalid integer '%ls'", arg.c_str()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in this case it'd be wiser to let an error()
bubble up onto the wcstring_list_t errors
list to be handled uniformly, rather than call debug
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, that's probably the right thing to do but I need to think about it. The problem with that approach is it loses context if we ever fix isssue #2860. I need to better understand how the errors list is utilized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
J.H.C. Switching to appending to the streams.err
stream does not allow redirecting such errors to /dev/null. It's still the right thing to do but clearly doesn't allow such errors to be silently discarded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't mean appending the string directly to streams.err
, but rather use the test_parser::error()
or add_error
or any other means to get it onto the errors
list on test_parser
. It may be necessary to check the state of errno
instead after using parse_number
(because you can't return anything but true or false here, or access errors
) and catch that in some caller above (binary_primary_evaluate
?), or perhaps check for a sane number at some other stage in evaluation.
The
test
builtin currently has unexpected behavior with respect toexpressions such as
'' -eq 0
. That currently evaluates to true with areturn status of zero. This change addresses that oddity while also
ensuring that other unusual strings (e.g., numbers with leading and
trailing whitespace) are handled consistently.
I based this on PR #3579 so it includes commits not already merged to the master branch. The only commit that is relevant for this PR is the final one: 210296b.