<feed xmlns='http://www.w3.org/2005/Atom'>
<title>musl/src/stdio, branch v1.1.16</title>
<subtitle>musl - an implementation of the standard library for Linux-based systems</subtitle>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/'/>
<entry>
<title>fix swprintf internal buffer state and error handling</title>
<updated>2016-11-08T01:39:59+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-11-08T01:39:59+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=7442442ccc665641a8827177e8e7ed45bbbd6584'/>
<id>7442442ccc665641a8827177e8e7ed45bbbd6584</id>
<content type='text'>
the swprintf write callback never reset its buffer pointers, so after
its 256-byte buffer filled up, it would keep repeating those bytes
over and over in the output until the destination buffer filled up. it
also failed to set the error indicator for the stream on EILSEQ,
potentially allowing output to continue after the error.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the swprintf write callback never reset its buffer pointers, so after
its 256-byte buffer filled up, it would keep repeating those bytes
over and over in the output until the destination buffer filled up. it
also failed to set the error indicator for the stream on EILSEQ,
potentially allowing output to continue after the error.
</pre>
</div>
</content>
</entry>
<entry>
<title>redesign snprintf without undefined behavior</title>
<updated>2016-10-22T02:15:31+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-10-22T00:57:15+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=ed8696742504b6182954254e78ec123c8bcd8d3b'/>
<id>ed8696742504b6182954254e78ec123c8bcd8d3b</id>
<content type='text'>
the old snprintf design setup the FILE buffer pointers to point
directly into the destination buffer; if n was actually larger than
the buffer size, the pointer arithmetic to compute the buffer end
pointer was undefined. this affected sprintf, which is implemented in
terms of snprintf, as well as some unusual but valid direct uses of
snprintf.

instead, setup the FILE as unbuffered and have its write function
memcpy to the destination. the printf core sets up its own temporary
buffer for unbuffered streams.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the old snprintf design setup the FILE buffer pointers to point
directly into the destination buffer; if n was actually larger than
the buffer size, the pointer arithmetic to compute the buffer end
pointer was undefined. this affected sprintf, which is implemented in
terms of snprintf, as well as some unusual but valid direct uses of
snprintf.

instead, setup the FILE as unbuffered and have its write function
memcpy to the destination. the printf core sets up its own temporary
buffer for unbuffered streams.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix float formatting of some exact halfway cases</title>
<updated>2016-10-20T05:54:15+00:00</updated>
<author>
<name>Szabolcs Nagy</name>
<email>nsz@port70.net</email>
</author>
<published>2016-10-11T22:49:59+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=51ab6db4ed115d079d7131975e4adb074ba9ef9d'/>
<id>51ab6db4ed115d079d7131975e4adb074ba9ef9d</id>
<content type='text'>
in nearest rounding mode exact halfway cases were not following the
round to even rule if the rounding happened at a base 1000000000 digit
boundary of the internal representation and the previous digit was odd.

e.g. printf("%.0f", 1.5) printed 1 instead of 2.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
in nearest rounding mode exact halfway cases were not following the
round to even rule if the rounding happened at a base 1000000000 digit
boundary of the internal representation and the previous digit was odd.

e.g. printf("%.0f", 1.5) printed 1 instead of 2.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix integer overflows and uncaught EOVERFLOW in printf core</title>
<updated>2016-10-20T04:22:09+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-10-20T04:22:09+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=167dfe9672c116b315e72e57a55c7769f180dffa'/>
<id>167dfe9672c116b315e72e57a55c7769f180dffa</id>
<content type='text'>
this patch fixes a large number of missed internal signed-overflow
checks and errors in determining when the return value (output length)
would exceed INT_MAX, which should result in EOVERFLOW. some of the
issues fixed were reported by Alexander Cherepanov; others were found
in subsequent review of the code.

aside from the signed overflows being undefined behavior, the
following specific bugs were found to exist in practice:

- overflows computing length of floating point formats with huge
  explicit precisions, integer formats with prefix characters and huge
  explicit precisions, or string arguments or format strings longer
  than INT_MAX, resulted in wrong return value and wrong %n results.

- literal width and precision values outside the range of int were
  misinterpreted, yielding wrong behavior in at least one well-defined
  case: string formats with precision greater than INT_MAX were
  sometimes truncated.

- in cases where EOVERFLOW is produced, incorrect values could be
  written for %n specifiers past the point of exceeding INT_MAX.

in addition to fixing these bugs, we now stop producing output
immediately when output length would exceed INT_MAX, rather than
continuing and returning an error only at the end.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
this patch fixes a large number of missed internal signed-overflow
checks and errors in determining when the return value (output length)
would exceed INT_MAX, which should result in EOVERFLOW. some of the
issues fixed were reported by Alexander Cherepanov; others were found
in subsequent review of the code.

aside from the signed overflows being undefined behavior, the
following specific bugs were found to exist in practice:

- overflows computing length of floating point formats with huge
  explicit precisions, integer formats with prefix characters and huge
  explicit precisions, or string arguments or format strings longer
  than INT_MAX, resulted in wrong return value and wrong %n results.

- literal width and precision values outside the range of int were
  misinterpreted, yielding wrong behavior in at least one well-defined
  case: string formats with precision greater than INT_MAX were
  sometimes truncated.

- in cases where EOVERFLOW is produced, incorrect values could be
  written for %n specifiers past the point of exceeding INT_MAX.

in addition to fixing these bugs, we now stop producing output
immediately when output length would exceed INT_MAX, rather than
continuing and returning an error only at the end.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix integer overflow in float printf needed-precision computation</title>
<updated>2016-10-20T00:17:16+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-10-20T00:17:16+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=70d2687d85c314963cf280759b23fd4573ff0d82'/>
<id>70d2687d85c314963cf280759b23fd4573ff0d82</id>
<content type='text'>
if the requested precision is close to INT_MAX, adding
LDBL_MANT_DIG/3+8 overflows. in practice the resulting undefined
behavior manifests as a large negative result, which is then used to
compute the new end pointer (z) with a wildly out-of-bounds value
(more overflow, more undefined behavior). the end result is at least
incorrect output and character count (return value); worse things do
not seem to happen, but detailed analysis has not been done.

this patch fixes the overflow by performing the intermediate
computation as unsigned; after division by 9, the final result
necessarily fits in int.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
if the requested precision is close to INT_MAX, adding
LDBL_MANT_DIG/3+8 overflows. in practice the resulting undefined
behavior manifests as a large negative result, which is then used to
compute the new end pointer (z) with a wildly out-of-bounds value
(more overflow, more undefined behavior). the end result is at least
incorrect output and character count (return value); worse things do
not seem to happen, but detailed analysis has not been done.

this patch fixes the overflow by performing the intermediate
computation as unsigned; after division by 9, the final result
necessarily fits in int.
</pre>
</div>
</content>
</entry>
<entry>
<title>simplify/refactor fflush and make fflush_unlocked an alias for fflush</title>
<updated>2016-09-19T01:45:47+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-09-19T01:45:47+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=c002668eb0352e619ea7064e4940b397b4a6e68d'/>
<id>c002668eb0352e619ea7064e4940b397b4a6e68d</id>
<content type='text'>
previously, fflush_unlocked was an alias for an internal backend that
was called by fflush, either for its argument or in a loop for each
file if a null pointer was passed. since the logic for the latter was
in the main fflush function, fflush_unlocked crashed when passed a
null pointer, rather than flushing all open files. since
fflush_unlocked is not a standard function and has no specification,
it's not clear whether it should be expected to accept null pointers
like fflush does, but a reasonable argument could be made that it
should.

this patch eliminates the helper function, simplifying fflush, and
makes fflush_unlocked an alias for fflush, which is valid because the
two functions agree in their behavior in all cases where their
behavior is defined (the unlocked version has undefined behavior if
another thread could hold locks).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
previously, fflush_unlocked was an alias for an internal backend that
was called by fflush, either for its argument or in a loop for each
file if a null pointer was passed. since the logic for the latter was
in the main fflush function, fflush_unlocked crashed when passed a
null pointer, rather than flushing all open files. since
fflush_unlocked is not a standard function and has no specification,
it's not clear whether it should be expected to accept null pointers
like fflush does, but a reasonable argument could be made that it
should.

this patch eliminates the helper function, simplifying fflush, and
makes fflush_unlocked an alias for fflush, which is valid because the
two functions agree in their behavior in all cases where their
behavior is defined (the unlocked version has undefined behavior if
another thread could hold locks).
</pre>
</div>
</content>
</entry>
<entry>
<title>fix printf regression with alt-form octal, zero flag, and field width</title>
<updated>2016-09-16T21:40:08+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-09-16T21:40:08+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=78897b0dc00b7cd5c29af5e0b7eebf2396d8dce0'/>
<id>78897b0dc00b7cd5c29af5e0b7eebf2396d8dce0</id>
<content type='text'>
commit b91cdbe2bc8b626aa04dc6e3e84345accf34e4b1, in fixing another
issue, changed the logic for how alt-form octal adds the leading zero
to adjust the precision rather than using a prefix character. this
wrongly suppressed the zero flag by mimicing an explicit precision
given by the format string. switch back to using a prefix character.

based on bug report and patch by Dmitry V. Levin, but simplified.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit b91cdbe2bc8b626aa04dc6e3e84345accf34e4b1, in fixing another
issue, changed the logic for how alt-form octal adds the leading zero
to adjust the precision rather than using a prefix character. this
wrongly suppressed the zero flag by mimicing an explicit precision
given by the format string. switch back to using a prefix character.

based on bug report and patch by Dmitry V. Levin, but simplified.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix FILE buffer underflow in ungetwc</title>
<updated>2016-04-26T19:26:40+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-04-26T19:26:40+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=6ed791e768d83b40ed56c99dbb1ed72c1e49aae7'/>
<id>6ed791e768d83b40ed56c99dbb1ed72c1e49aae7</id>
<content type='text'>
commit 7e816a6487932cbb3cb71d94b609e50e81f4e5bf (version 1.1.11
release cycle) moved the code that performs wchar_t to multibyte
conversion across code that used the resulting length in bytes,
thereby breaking the unget buffer space check in ungetwc and
clobbering up to three bytes below the start of the buffer.

for allocated FILEs (all read-enabled FILEs except stdin), the
underflow clobbers at most the FILE-specific locale pointer. no stores
are performed through this pointer, but subsequent loads may result in
a crash or mismatching encoding rule (UTF-8 multibyte vs byte-based).

for stdin, the buffer lies in .bss and the underflow may clobber
another object. in practice, for libc.so the adjacent object seems to
be stderr's buffer, which is completely unused, but this could vary
with linking options, or when static linking.

applications which do not attempt to use more than one character of
ungetwc pushback, or which do not use ungetwc, are not affected.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 7e816a6487932cbb3cb71d94b609e50e81f4e5bf (version 1.1.11
release cycle) moved the code that performs wchar_t to multibyte
conversion across code that used the resulting length in bytes,
thereby breaking the unget buffer space check in ungetwc and
clobbering up to three bytes below the start of the buffer.

for allocated FILEs (all read-enabled FILEs except stdin), the
underflow clobbers at most the FILE-specific locale pointer. no stores
are performed through this pointer, but subsequent loads may result in
a crash or mismatching encoding rule (UTF-8 multibyte vs byte-based).

for stdin, the buffer lies in .bss and the underflow may clobber
another object. in practice, for libc.so the adjacent object seems to
be stderr's buffer, which is completely unused, but this could vary
with linking options, or when static linking.

applications which do not attempt to use more than one character of
ungetwc pushback, or which do not use ungetwc, are not affected.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix undefined pointer comparison in stdio-internal __toread</title>
<updated>2016-03-29T03:41:17+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-03-29T03:41:17+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=6d1a3dfeaf2caac4033a3c65822fb4e7e14866c7'/>
<id>6d1a3dfeaf2caac4033a3c65822fb4e7e14866c7</id>
<content type='text'>
the comparison f-&gt;wpos &gt; f-&gt;buf has undefined behavior when f-&gt;wpos is
a null pointer, despite the intuition (and actual compiler behavior,
for all known compilers) being that NULL &gt; ptr is false for all valid
pointers ptr.

the purpose of the comparison is to determine if the write buffer is
non-empty, and the idiom used elsewhere for that is comparison against
f-&gt;wbase, which is either a null pointer when not writing, or equal to
f-&gt;buf when writing. in the former case, both f-&gt;wpos and f-&gt;wbase are
null; in the latter they are both non-null and point into the same
array.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the comparison f-&gt;wpos &gt; f-&gt;buf has undefined behavior when f-&gt;wpos is
a null pointer, despite the intuition (and actual compiler behavior,
for all known compilers) being that NULL &gt; ptr is false for all valid
pointers ptr.

the purpose of the comparison is to determine if the write buffer is
non-empty, and the idiom used elsewhere for that is comparison against
f-&gt;wbase, which is either a null pointer when not writing, or equal to
f-&gt;buf when writing. in the former case, both f-&gt;wpos and f-&gt;wbase are
null; in the latter they are both non-null and point into the same
array.
</pre>
</div>
</content>
</entry>
<entry>
<title>fix padding string formats to width in wide printf variants</title>
<updated>2016-03-16T20:35:22+00:00</updated>
<author>
<name>Rich Felker</name>
<email>dalias@aerifal.cx</email>
</author>
<published>2016-03-16T20:35:22+00:00</published>
<link rel='alternate' type='text/html' href='http://git.musl-libc.org/cgit/musl/commit/?id=4aac019a0efd59011a48d031ad046c934c7e8365'/>
<id>4aac019a0efd59011a48d031ad046c934c7e8365</id>
<content type='text'>
the idiom fprintf(f, "%.*s", n, "") was wrongly used in vfwprintf as a
means of producing n spaces; instead it produces no output. the
correct form is fprintf(f, "%*s", n, ""), using width instead of
precision, since for %s the later is a maximum rather than a minimum.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
the idiom fprintf(f, "%.*s", n, "") was wrongly used in vfwprintf as a
means of producing n spaces; instead it produces no output. the
correct form is fprintf(f, "%*s", n, ""), using width instead of
precision, since for %s the later is a maximum rather than a minimum.
</pre>
</div>
</content>
</entry>
</feed>
