casaroli opened a new pull request, #21106:
URL: https://github.com/apache/nuttx/pull/21106

   ## Summary
   
   Three small libc bugs, one commit each, each with a test that fails on 
master.
   
   ### getdelim-eof
   
   `getdelim()` and `getline()` return -1 at the end of the file also when they 
read characters before it. So the last line of a stream that does not end with 
the delimiter is lost. POSIX returns the characters read, and -1 only if no 
characters were read at the end of the file, or on a read error. glibc and musl 
do the same.
   
   This PR returns the characters read before the end of the file, 
NUL-terminated. The next call returns -1 with the end-of-file indicator set.
   
   ### printf-quote-flag
   
   The XSI flag `'` groups the integer digits of `%d`, `%i`, `%u`, `%f`, `%F`, 
`%g` and `%G` with the thousands separator of the locale. `printf()` does not 
know the flag: it stops the conversion there and prints the rest of the 
conversion specification as text, so `"%'d"` prints `%'d`.
   
   This PR accepts the flag and prints the number without grouping: the C 
locale has no thousands separator.
   
   ### crypt-md5
   
   `crypt_r()` (and `crypt()`) compute MD5 through `/dev/crypto` and ignored 
the result of each step. Without `/dev/crypto` (no `CONFIG_CRYPTO_CRYPTODEV`), 
or when an `ioctl()` failed, they returned `"$1$<salt>$"` followed by a hash of 
whatever was in the buffer, not an error. On some failure paths the session or 
the file also stayed open.
   
   This PR keeps the first error of a step in the context. The later steps do 
nothing, and `md5_finish()` closes the session and the file on every path and 
returns the error. `crypt_r()` then returns NULL with `errno` set. A salt that 
is not `"$1$"` and a key that is too long also set `EINVAL` (they returned NULL 
with `errno` unchanged).
   
   ## Impact
   
   - getdelim-eof: `getline()` and `getdelim()` return the last line of a 
stream that does not end with the delimiter. A loop `while (getline(...) != 
-1)` now also sees that line. All build modes and architectures. Documentation: 
no change (`Documentation/standards/posix.rst` already lists both functions as 
supported).
   - printf-quote-flag: Formats with `'` print the number, as in the C locale 
of other C libraries. All build modes and architectures. Documentation: no 
change.
   - crypt-md5: - Without `/dev/crypto`, `crypt()` returns NULL with `errno` 
(`ENOENT`) instead of a wrong hash. - With a working cryptodev, the hash does 
not change. - Only with `CONFIG_CRYPTO` (the file is built only then); all 
build modes, nothing per architecture. No documentation describes `crypt()`.
   
   ## Testing
   
   The branches were first tested one by one (below). Then all commits of this 
PR together, on master b79dc18e015: getdelimeof.c, printfq.c 
(CONFIG_LIBC_FLOATINGPOINT), cryptmd5.c (CONFIG_CRYPTO) on `qemu-armv8a:knsh` 
(QEMU with HVF) all PASS, and ostest exits with status 0 on `qemu-armv8a:knsh` 
and `qemu-armv8a:nsh`.
   
   ### getdelim-eof
   
   Test program `getdelimeof.c` (streams from `fmemopen()`):
   
   | Case | master | this PR |
   |---|---|---|
   | `"one\ntwo"`: 4 `"one\n"`, 3 `"two"`, then -1 and `feof()` | FAIL (-1 for 
`"two"`) | PASS |
   | `getdelim(',')` of `"a,bc"`: 2 `"a,"`, 2 `"bc"`, then -1 | FAIL (-1 for 
`"bc"`) | PASS |
   | `"x\n"`: 2 `"x\n"`, then -1 (no empty line after it) | PASS | PASS |
   | a last line of 300 characters without a newline: 300 | FAIL (-1) | PASS |
   
   Run on `qemu-armv8a:knsh` (kernel, arm64, QEMU with HVF): master 3 FAIL, 1 
PASS; this PR all PASS. ostest exits with status 0 on `qemu-armv8a:knsh` and 
`qemu-armv8a:nsh` (flat).
   
   Build, each OK (master aeab6fbf989 with this change and other small 
independent fixes): `rv-virt:pnsh64` (protected, rv64), `rv-virt:knsh64` 
(kernel, rv64), `mps2-an500:nsh` (flat, armv7-m, GCC 13.2), `mps2-an500:knsh` 
(protected, armv7-m), `qemu-armv8a:nsh_smp` (flat, SMP), and `qemu-armv8a:nsh` 
with CMake.
   
   No test in nuttx-apps covers `getdelim()` at the end of a file.
   
   ### printf-quote-flag
   
   Test program `printfq.c` (`snprintf()`), with `CONFIG_LIBC_FLOATINGPOINT`:
   
   | Format | master | this PR |
   |---|---|---|
   | `%'d` 1234567 | `%'d` | `1234567` |
   | `%'9d` 1234567 | `%'9d` | `  1234567` |
   | `%'lu` 4000000000 | `%'lu` | `4000000000` |
   | `%'.0f` 1500.0 | `%'.0f` | `1500` |
   | `%-'6d\|` 42 | `%'6d\|` | `42    \|` |
   | `%'dB %s` 7, "ok" | `%'dB ok` | `7B ok` |
   
   Run on `qemu-armv8a:knsh` (kernel, arm64, QEMU with HVF). ostest exits with 
status 0 on `qemu-armv8a:knsh` and `qemu-armv8a:nsh` (flat).
   
   Build, each OK (master aeab6fbf989 with this change and other small 
independent fixes): `rv-virt:pnsh64` (protected, rv64), `rv-virt:knsh64` 
(kernel, rv64), `mps2-an500:nsh` (flat, armv7-m, GCC 13.2), `mps2-an500:knsh` 
(protected, armv7-m), `qemu-armv8a:nsh_smp` (flat, SMP), and `qemu-armv8a:nsh` 
with CMake.
   
   No test in nuttx-apps covers the flag.
   
   ### crypt-md5
   
   Test program `cryptmd5.c` (`md5`: with `/dev/crypto`, the hash of "test" 
with "$1$saltsalt$" must be "$1$saltsalt$tTWg0JeO/sYmHvtKmZE8c.", the value of 
glibc and libxcrypt; without `/dev/crypto`, NULL; `des`: a salt that is not 
"$1$" gives NULL and `EINVAL`), compiled against the export of qemu-armv8a:knsh 
(kernel build) and run under QEMU (HVF):
   
   | Config | master aeab6fbf989 | this PR |
   |---|---|---|
   | knsh + `CRYPTO` (no `/dev/crypto`) | `md5` FAIL 
("$1$saltsalt$hq8.SvhrhqOfSvhrSrOfS1"), `des` FAIL (NULL, errno 0) | `md5` PASS 
(NULL, `ENOENT`), `des` PASS (NULL, `EINVAL`) |
   | knsh + software cryptodev (`ALLOW_BSD_COMPONENTS`, `CRYPTO_SW_AES`, 
`CRYPTO_CRYPTODEV`, `CRYPTO_CRYPTODEV_SOFTWARE_CRYPTO`) | not run | `md5` PASS 
(the glibc hash), `des` PASS |
   
   ostest exits with status 0 on qemu-armv8a:knsh (kernel) and qemu-armv8a:nsh 
(flat), both with `CONFIG_CRYPTO`.
   
   Builds with `CONFIG_CRYPTO` (`lib_crypt_r.c` compiled), each without new 
warnings: stm32f4discovery:nsh (flat, Cortex-M4), rv-virt:pnsh64 (protected, 
RISC-V) and rv-virt:knsh64 (kernel, RISC-V).
   
   `tools/checkpatch.sh -c -u -m -g` passes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to