bug report: ksh: incorrect "$@" handling with null (empty) IFS

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

bug report: ksh: incorrect "$@" handling with null (empty) IFS

NOTE: I was requested on IRC to post to the list but otherwise I'm
not following it, nor using OpenBSD regularly.
Please CC me for any comment.

uname -a (running inside virtual box):
OpenBSD foo.my.domain 6.7 GENERIC.MP#182 amd64

Run the following command:
/bin/sh -c 'IFS=; args() { printf "[%s]" "$@"; }; args 1 2 3'

Expected result:

Actual result:
[1 2 3]

It seems that "$@" in [k]sh with IFS as null combines the arguments
as if it was "$*" when IFS is unset or begins with space, while in
fact the main difference between (quoted) "$@" and $* is that the
former should retain the individual arguments regardless of IFS,
while $* combines them with the first char of IFS (or space if IFS
is unset).

The same issue exists also at pdksh 5.2.14, but not at any other
shell which I tested (dash 5.8 up to master, busybox-ash, bash, ksh93,
mksh, bosh, and others).

As far as I can interpret the POSIX specifications and as far as other
shells which I tested behave, it seems to be a bug in pdksh which is
inherited by OpenBSD ksh.

As an anecdote why this behavior is undesirable, consider the pattern:
while IFS= read -r line; do ...; done

and imagine that `read' was implemented as a function which then
calls another function, e.g.: read() { read_internal "$@"; }

With the current behavior, read_internal will see one argument
"-r line" instead of two: "-r" and "line", and could never work

Example of this flow (ignore the general badness of echo):
sh -c 'foo() { for x; do echo [$x]; done; }; bar() { foo "$@"; }; IFS=; bar -r line'

prints [-r line] as one argument instead of [-r]<\n>[line]<\n>

Best regards,
Avi Halachmi

I was requested to attach dmesg, so here it is:

OpenBSD 6.7 (GENERIC.MP) #182: Thu May  7 11:11:58 MDT 2020
    [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 4278124544 (4079MB)
avail mem = 4135845888 (3944MB)
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.5 @ 0xe1000 (10 entries)
bios0: vendor innotek GmbH version "VirtualBox" date 12/01/2006
bios0: innotek GmbH VirtualBox
acpi0 at bios0: ACPI 4.0
acpi0: sleep states S0 S5
acpi0: tables DSDT FACP APIC SSDT
acpi0: wakeup devices
acpitimer0 at acpi0: 3579545 Hz, 32 bits
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, 2208.44 MHz, 06-9e-0a
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: CPU supports MTRRs but not enabled by BIOS
cpu0: apic clock running at 1000MHz
cpu1 at mainbus0: apid 1 (application processor)
cpu1: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, 2208.44 MHz, 06-9e-0a
cpu1: 256KB 64b/line 8-way L2 cache
cpu1: smt 0, core 1, package 0
cpu2 at mainbus0: apid 2 (application processor)
cpu2: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, 2208.67 MHz, 06-9e-0a
cpu2: 256KB 64b/line 8-way L2 cache
cpu2: smt 0, core 2, package 0
cpu3 at mainbus0: apid 3 (application processor)
cpu3: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, 2209.88 MHz, 06-9e-0a
cpu3: 256KB 64b/line 8-way L2 cache
cpu3: smt 0, core 3, package 0
cpu4 at mainbus0: apid 4 (application processor)
cpu4: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, 2209.71 MHz, 06-9e-0a
cpu4: 256KB 64b/line 8-way L2 cache
cpu4: smt 0, core 0, package 1
cpu5 at mainbus0: apid 5 (application processor)
cpu5: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz, 2218.69 MHz, 06-9e-0a
cpu5: 256KB 64b/line 8-way L2 cache
cpu5: smt 0, core 1, package 1
ioapic0 at mainbus0: apid 6 pa 0xfec00000, version 20, 24 pins, remapped
acpiprt0 at acpi0: bus 0 (PCI0)
acpicpu0 at acpi0: C1(@1 halt!)
acpicpu1 at acpi0: C1(@1 halt!)
acpicpu2 at acpi0: C1(@1 halt!)
acpicpu3 at acpi0: C1(@1 halt!)
acpicpu4 at acpi0: C1(@1 halt!)
acpicpu5 at acpi0: C1(@1 halt!)
acpipci0 at acpi0 PCI0: 0x00000000 0x00000011 0x00000001
acpibat0 at acpi0: BAT0 model "1" serial 0 type VBOX oem "innotek"
acpiac0 at acpi0: AC unit online
acpivideo0 at acpi0: GFX0
cpu0: using VERW MDS workaround (except on vmm entry)
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel 82441FX" rev 0x02
pcib0 at pci0 dev 1 function 0 "Intel 82371SB ISA" rev 0x00
pciide0 at pci0 dev 1 function 1 "Intel 82371AB IDE" rev 0x01: DMA, channel 0 configured to compatibility, channel 1 configured to compatibility
wd0 at pciide0 channel 0 drive 0: <VBOX HARDDISK>
wd0: 128-sector PIO, LBA, 16384MB, 33554432 sectors
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2
atapiscsi0 at pciide0 channel 1 drive 0
scsibus1 at atapiscsi0: 2 targets
cd0 at scsibus1 targ 0 lun 0: <VBOX, CD-ROM, 1.0> removable
cd0(pciide0:1:0): using PIO mode 4, Ultra-DMA mode 2
vga1 at pci0 dev 2 function 0 "InnoTek VirtualBox Graphics Adapter" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
em0 at pci0 dev 3 function 0 "Intel 82540EM" rev 0x02: apic 6 int 19, address 08:00:27:54:b0:69
"InnoTek VirtualBox Guest Service" rev 0x00 at pci0 dev 4 function 0 not configured
auich0 at pci0 dev 5 function 0 "Intel 82801AA AC97" rev 0x01: apic 6 int 21, ICH
ac97: codec id 0x83847600 (SigmaTel STAC9700)
audio0 at auich0
ohci0 at pci0 dev 6 function 0 "Apple Intrepid USB" rev 0x00: apic 6 int 22, version 1.0
piixpm0 at pci0 dev 7 function 0 "Intel 82371AB Power" rev 0x08: apic 6 int 23
iic0 at piixpm0
ehci0 at pci0 dev 11 function 0 "Intel 82801FB USB" rev 0x00: apic 6 int 19
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 configuration 1 interface 0 "Intel EHCI root hub" rev 2.00/1.00 addr 1
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
usb1 at ohci0: USB revision 1.0
uhub1 at usb1 configuration 1 interface 0 "Apple OHCI root hub" rev 1.00/1.00 addr 1
vscsi0 at root
scsibus2 at vscsi0: 256 targets
softraid0 at root
scsibus3 at softraid0: 256 targets
root on wd0a (4ef32fd6459c69c7.a) swap on wd0b dump on wd0b
WARNING: clock gained 4 days