On 4/17/23 15:15, Eric Blake wrote:
Exploit the value of the flag for -n to reduce the size of
readlink_main() (shown here with CONFIG_FEATURE_READLINK_FOLLOW off)
on x86_64.

function                                             old     new   delta
readlink_main                                        121     118      -3

Signed-off-by: Eric Blake<[email protected]>

---

v2: Add 'make bloatcheck' details
---
  coreutils/readlink.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/coreutils/readlink.c b/coreutils/readlink.c
index 0a9aa957e..83c417e66 100644
--- a/coreutils/readlink.c
+++ b/coreutils/readlink.c
@@ -88,7 +88,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)

        if (!buf)
                return EXIT_FAILURE;
-       printf((opt & 1) ? "%s" : "%s\n", buf);
+       printf("%s%s", buf, "\n"[opt & 1]);

I don’t think this works (as Tito empirically determined).

The type of "\n" is char const *, so subscripting that gives you just char, not a pointer. You then pass that char (either '\0' or '\n') to printf, but as %s, so it’s implicitly cast to a pointer inside printf.

Passing (char*)'\0' for %s results in "(null)" due to printf being graceful with NULL strings, but there’s no forgiveness for passing (char*)'\n', so you get a segfault. This is exactly the output Tito obtained when he tried out your patch.

What you probably meant to do here is

+       printf("%s%s", buf, "\n" + (opt & 1));

which evaluates to "" or "\n" due to (opt & 1) skipping \n or not.

        free(buf);

        fflush_stdout_and_exit_SUCCESS();

base-commit: d2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a


--
Raf

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to