Skip to content

Commit f6ba352

Browse files
[libc] Add nullptr check option to printf %s
Some printf implementations perform a null check on pointers passed to %s. While that's not in the standard, this patch adds it as an option for compatibility. It also puts a similar check in %n behind the same flag. Reviewed By: lntue Differential Revision: https://reviews.llvm.org/D156923
1 parent 07c8bcc commit f6ba352

File tree

4 files changed

+22
-9
lines changed

4 files changed

+22
-9
lines changed

libc/src/stdio/printf_core/printf_config.h

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

4040
// TODO(michaelrj): Move the other printf configuration options into this file.
4141

42+
// LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
43+
4244
#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_PRINTF_CONFIG_H

libc/src/stdio/printf_core/string_converter.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,15 @@ namespace printf_core {
2222

2323
LIBC_INLINE int convert_string(Writer *writer, const FormatSection &to_conv) {
2424
size_t string_len = 0;
25+
const char *str_ptr = reinterpret_cast<const char *>(to_conv.conv_val_ptr);
2526

26-
for (char *cur_str = reinterpret_cast<char *>(to_conv.conv_val_ptr);
27-
cur_str[string_len]; ++string_len) {
27+
#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
28+
if (str_ptr == nullptr) {
29+
str_ptr = "null";
30+
}
31+
#endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
32+
33+
for (const char *cur_str = (str_ptr); cur_str[string_len]; ++string_len) {
2834
;
2935
}
3036

@@ -42,8 +48,7 @@ LIBC_INLINE int convert_string(Writer *writer, const FormatSection &to_conv) {
4248
RET_IF_RESULT_NEGATIVE(writer->write(' ', padding_spaces));
4349
}
4450

45-
RET_IF_RESULT_NEGATIVE(writer->write(
46-
{reinterpret_cast<const char *>(to_conv.conv_val_ptr), string_len}));
51+
RET_IF_RESULT_NEGATIVE(writer->write({(str_ptr), string_len}));
4752

4853
// If the padding is on the right side, write the spaces last.
4954
if (padding_spaces > 0 &&

libc/src/stdio/printf_core/write_int_converter.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@ namespace printf_core {
2222
LIBC_INLINE int convert_write_int(Writer *writer,
2323
const FormatSection &to_conv) {
2424

25-
// This is an additional check added by LLVM-libc. The reason it returns -3 is
26-
// because printf uses negative return values for errors, and -1 and -2 are
27-
// already in use by the file_writer class for file errors.
28-
// TODO: Remove this. It's better to crash than to provide an incorrect
29-
// result.
25+
#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
26+
// This is an additional check added by LLVM-libc.
3027
if (to_conv.conv_val_ptr == nullptr)
3128
return NULLPTR_WRITE_ERROR;
29+
#endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
3230

3331
int written = writer->get_chars_written();
3432

libc/test/src/stdio/sprintf_test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ TEST(LlvmLibcSPrintfTest, StringConv) {
9696
"isn't", 12, 10, "important. Ever.");
9797
EXPECT_EQ(written, 26);
9898
ASSERT_STREQ(buff, " beginning is important.");
99+
100+
#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
101+
written = __llvm_libc::sprintf(buff, "%s", nullptr);
102+
EXPECT_EQ(written, 4);
103+
ASSERT_STREQ(buff, "null");
104+
#endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
99105
}
100106

101107
TEST(LlvmLibcSPrintfTest, IntConv) {
@@ -2781,8 +2787,10 @@ TEST(LlvmLibcSPrintfTest, WriteIntConv) {
27812787
EXPECT_EQ(test_val, 8);
27822788
ASSERT_STREQ(buff, "87654321");
27832789

2790+
#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
27842791
written = __llvm_libc::sprintf(buff, "abc123%n", nullptr);
27852792
EXPECT_LT(written, 0);
2793+
#endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
27862794
}
27872795
#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
27882796

0 commit comments

Comments
 (0)