| Summary: | sh: fix sh -c -e cmd as per POSIX | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | Christian Weisgerber <naddy> | ||||
| Component: | standards | Assignee: | freebsd-standards (Nobody) <standards> | ||||
| Status: | New --- | ||||||
| Severity: | Affects Some People | CC: | jilles, nimaje+fbz, rb | ||||
| Priority: | --- | ||||||
| Version: | CURRENT | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
this needs to fix system(3) as well as popen(3) too, as currently they call sh -c <command> with this change, that is no longer safe and needs to call sh -c -- <command> See also: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274650 (should that bug depend on this one?) (In reply to Benjamin Takacs from comment #1) Also probably the examples in su(1) where there is a `-c' minefield. And actually this affects any code that calls `sh -c ....' directly. This is getting dangerously close to a POLA violation, POSIX notwithstanding. (In reply to Bob Bishop from comment #2) (In reply to Bob Bishop from comment #3) This being such a footgun is why I argue in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274650#c1 for just documenting our sh to be *not* posix compatible on some stuff and leave -c alone. It doesn't break any realistic existing usage of sh -c cmd. (In reply to Christian Weisgerber from comment #5) I just listed two that became incorrect. system(3) and popen(3). How do you know I don't use - as prefix to mark internal commands and build commandlines run them via system, popen or sh -c? The patch in https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=220587 has more test cases. Another thing that will break with the fixed -c is the ruby ports (not because of the upstream code but because of scripting in the port itself): https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222872 . (In reply to Benjamin Takacs from comment #6) That takes me to my starting point, which was a discussion about shell scripting where somebody was bending over backwards to use POSIX-ly correct code that handled all corner cases, so he used "sh -c --" and was quite astonished when I pointed out that this breaks on FreeBSD. Obviously system(3) and popen(3) will need to be fixed accordingly. |
Created attachment 250294 [details] fix sh -c -e cmd as per POSIX POSIX requires sh(1) to handle -c like an option that does not take an argument. We already handle the special case of attached options after -c... $ sh -ce 'echo hello world' hello world ... but these fail: $ sh -c -e 'echo hello world' echo hello world: -e: not found $ sh -c -- 'echo hello world' echo hello world: --: not found NetBSD fixed this 21 years ago. With their fix: $ sh -c -e 'echo hello world' hello world $ sh -c -- 'echo hello world' hello world $ sh -c -e 'echo hello; false; echo world' hello Patch attached. I also added a minimal regression test. I have only tested this on 14-STABLE, but there are no relevant changes between 14-STABLE and 15-CURRENT in sh.