Skip to content

Commit 9cb3d5e

Browse files
sunfishcodenicholasbishop
authored andcommitted
Support NULL pointers in '%s'
glibc, musl, and other common libc implementations allow a NULL pointer to be passed to the `%s` specifier, and format it as "(null)". This patch adds support to printf-compat to do the same.
1 parent 6aa8f0f commit 9cb3d5e

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
* Remove dependency on `alloc`.
66
<https://github.com/lights0123/printf-compat/pull/25>
7+
* Output `(null)` when a null pointer is formatted with `%s`.
8+
<https://github.com/lights0123/printf-compat/pull/31>
79

810
## 0.2.0 (July 14, 2025)
911

src/parser.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,16 @@ pub unsafe fn format(
187187
value: args.arg(),
188188
format: DoubleFormat::Hex.set_upper(ch.is_ascii_uppercase()),
189189
},
190-
b's' => Specifier::String(CStr::from_ptr(args.arg())),
190+
b's' => {
191+
let arg: *mut c_char = args.arg();
192+
// As a common extension supported by glibc, musl, and
193+
// others, format a NULL pointer as "(null)".
194+
if arg.is_null() {
195+
Specifier::Bytes(b"(null)")
196+
} else {
197+
Specifier::String(CStr::from_ptr(arg))
198+
}
199+
}
191200
b'c' => Specifier::Char(args.arg::<u32>() as u8),
192201
b'p' => Specifier::Pointer(args.arg()),
193202
b'n' => Specifier::WriteBytesWritten(written, args.arg()),

src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ fn test_str() {
7373
assert_eq_fmt!(c_str!("%10.4s"), c_str!("world"));
7474
assert_eq_fmt!(c_str!("%-10.4s"), c_str!("world"));
7575
assert_eq_fmt!(c_str!("%-10s"), c_str!("world"));
76+
assert_eq_fmt!(c_str!("%s"), null_mut::<c_char>());
7677
}
7778
}
7879

0 commit comments

Comments
 (0)