Skip to content

Commit a841cf9

Browse files
authored
[lib++][print] Don't pad the ostream output. (#128354)
Per [ostream.formatted.reqmts]/3 padding should only be done when explicitly stated. Fixes: #116054
1 parent d7b3606 commit a841cf9

File tree

4 files changed

+23
-81
lines changed

4 files changed

+23
-81
lines changed

libcxx/include/__ostream/print.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,11 @@ __vprint_nonunicode(ostream& __os, string_view __fmt, format_args __args, bool _
4949
if (__write_nl)
5050
__o += '\n';
5151

52-
const char* __str = __o.data();
53-
size_t __len = __o.size();
54-
5552
# if _LIBCPP_HAS_EXCEPTIONS
5653
try {
5754
# endif // _LIBCPP_HAS_EXCEPTIONS
58-
typedef ostreambuf_iterator<char> _Ip;
59-
if (std::__pad_and_output(
60-
_Ip(__os),
61-
__str,
62-
(__os.flags() & ios_base::adjustfield) == ios_base::left ? __str + __len : __str,
63-
__str + __len,
64-
__os,
65-
__os.fill())
66-
.failed())
55+
if (auto __rdbuf = __os.rdbuf();
56+
!__rdbuf || __rdbuf->sputn(__o.data(), __o.size()) != static_cast<streamsize>(__o.size()))
6757
__os.setstate(ios_base::badbit | ios_base::failbit);
6858

6959
# if _LIBCPP_HAS_EXCEPTIONS

libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/print.pass.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ static void test_write_failure() {
133133
assert(os.fail());
134134
}
135135

136+
// Test the formatting does no padding.
136137
static void test_stream_formatting() {
137138
std::stringstream sstr;
138139
auto test = [&]<class... Args>(std::string_view expected, test_format_string<char, Args...> fmt, Args&&... args) {
@@ -148,37 +149,20 @@ static void test_stream_formatting() {
148149
test("hello", "{}", "hello");
149150

150151
sstr.width(10);
151-
test(" hello", "{}", "hello");
152+
test("hello", "{}", "hello");
153+
assert(sstr.width() == 10);
152154

153155
sstr.fill('+');
154156

155157
sstr.width(10);
156-
test("+++++hello", "{}", "hello");
158+
test("hello", "{}", "hello");
159+
assert(sstr.width() == 10);
157160

158161
// *** Test embedded NUL character ***
159162
using namespace std::literals;
160163
sstr.width(15);
161-
test("++++hello\0world"sv, "hello{}{}", '\0', "world");
162-
163-
// *** Test Unicode ***
164-
// Streams count code units not code points
165-
// 2-byte code points
166-
sstr.width(5);
167-
test("+++\u00a1", "{}", "\u00a1"); // INVERTED EXCLAMATION MARK
168-
sstr.width(5);
169-
test("+++\u07ff", "{}", "\u07ff"); // NKO TAMAN SIGN
170-
171-
// 3-byte code points
172-
sstr.width(5);
173-
test("++\u0800", "{}", "\u0800"); // SAMARITAN LETTER ALAF
174-
sstr.width(5);
175-
test("++\ufffd", "{}", "\ufffd"); // REPLACEMENT CHARACTER
176-
177-
// 4-byte code points
178-
sstr.width(5);
179-
test("+\U00010000", "{}", "\U00010000"); // LINEAR B SYLLABLE B008 A
180-
sstr.width(5);
181-
test("+\U0010FFFF", "{}", "\U0010FFFF"); // Undefined Character
164+
test("hello\0world"sv, "hello{}{}", '\0', "world");
165+
assert(sstr.width() == 15);
182166
}
183167

184168
int main(int, char**) {

libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_nonunicode.pass.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ static void test_write_failure() {
149149
assert(os.fail());
150150
}
151151

152+
// Test the formatting does no padding.
152153
static void test_stream_formatting() {
153154
std::stringstream sstr;
154155
auto test = [&]<class... Args>(std::string_view expected, test_format_string<char, Args...> fmt, Args&&... args) {
@@ -164,37 +165,20 @@ static void test_stream_formatting() {
164165
test("hello", "{}", "hello");
165166

166167
sstr.width(10);
167-
test(" hello", "{}", "hello");
168+
test("hello", "{}", "hello");
169+
assert(sstr.width() == 10);
168170

169171
sstr.fill('+');
170172

171173
sstr.width(10);
172-
test("+++++hello", "{}", "hello");
174+
test("hello", "{}", "hello");
175+
assert(sstr.width() == 10);
173176

174177
// *** Test embedded NUL character ***
175178
using namespace std::literals;
176179
sstr.width(15);
177-
test("++++hello\0world"sv, "hello{}{}", '\0', "world");
178-
179-
// *** Test Unicode ***
180-
// Streams count code units not code points
181-
// 2-byte code points
182-
sstr.width(5);
183-
test("+++\u00a1", "{}", "\u00a1"); // INVERTED EXCLAMATION MARK
184-
sstr.width(5);
185-
test("+++\u07ff", "{}", "\u07ff"); // NKO TAMAN SIGN
186-
187-
// 3-byte code points
188-
sstr.width(5);
189-
test("++\u0800", "{}", "\u0800"); // SAMARITAN LETTER ALAF
190-
sstr.width(5);
191-
test("++\ufffd", "{}", "\ufffd"); // REPLACEMENT CHARACTER
192-
193-
// 4-byte code points
194-
sstr.width(5);
195-
test("+\U00010000", "{}", "\U00010000"); // LINEAR B SYLLABLE B008 A
196-
sstr.width(5);
197-
test("+\U0010FFFF", "{}", "\U0010FFFF"); // Undefined Character
180+
test("hello\0world"sv, "hello{}{}", '\0', "world");
181+
assert(sstr.width() == 15);
198182
}
199183

200184
int main(int, char**) {

libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/vprint_unicode.pass.cpp

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ static void test_write_failure() {
149149
assert(os.fail());
150150
}
151151

152+
// Test the formatting does no padding.
152153
static void test_stream_formatting() {
153154
std::stringstream sstr;
154155
auto test = [&]<class... Args>(std::string_view expected, test_format_string<char, Args...> fmt, Args&&... args) {
@@ -164,37 +165,20 @@ static void test_stream_formatting() {
164165
test("hello", "{}", "hello");
165166

166167
sstr.width(10);
167-
test(" hello", "{}", "hello");
168+
test("hello", "{}", "hello");
169+
assert(sstr.width() == 10);
168170

169171
sstr.fill('+');
170172

171173
sstr.width(10);
172-
test("+++++hello", "{}", "hello");
174+
test("hello", "{}", "hello");
175+
assert(sstr.width() == 10);
173176

174177
// *** Test embedded NUL character ***
175178
using namespace std::literals;
176179
sstr.width(15);
177-
test("++++hello\0world"sv, "hello{}{}", '\0', "world");
178-
179-
// *** Test Unicode ***
180-
// Streams count code units not code points
181-
// 2-byte code points
182-
sstr.width(5);
183-
test("+++\u00a1", "{}", "\u00a1"); // INVERTED EXCLAMATION MARK
184-
sstr.width(5);
185-
test("+++\u07ff", "{}", "\u07ff"); // NKO TAMAN SIGN
186-
187-
// 3-byte code points
188-
sstr.width(5);
189-
test("++\u0800", "{}", "\u0800"); // SAMARITAN LETTER ALAF
190-
sstr.width(5);
191-
test("++\ufffd", "{}", "\ufffd"); // REPLACEMENT CHARACTER
192-
193-
// 4-byte code points
194-
sstr.width(5);
195-
test("+\U00010000", "{}", "\U00010000"); // LINEAR B SYLLABLE B008 A
196-
sstr.width(5);
197-
test("+\U0010FFFF", "{}", "\U0010FFFF"); // Undefined Character
180+
test("hello\0world"sv, "hello{}{}", '\0', "world");
181+
assert(sstr.width() == 15);
198182
}
199183

200184
int main(int, char**) {

0 commit comments

Comments
 (0)