Description of problem: Reuse same buffer in sprintf, i.e., char buffer[50]="ABCDEF"; sprintf(buffer, "%s+%d", buffer, 123456) gives "+123456" instead of "ABCDEF+123456", i.e. buffer is truncated first to "\0" before concatenating with "+123456". Happens only with -D_FORTIFY_SOURCE=2 -O2 -O2 OR -D_FORTIFY_SOURCE=2 separately are ok. Version-Release number of selected component (if applicable): gcc 4.1.1-30 glibc 2.5-3 How reproducible: Always Steps to Reproduce: 1. Test file #include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { char buffer[50]; sprintf(buffer, "ABCDEF"); printf("%s\n", buffer); sprintf(buffer, "%s+%s", buffer, "123456"); printf("%s\n", buffer); } 2. Compile test file: gcc -o testing testing.c -O2 -Wp,-D_FORTIFY_SOURCE=2 3. Run ./testing Actual results: ABCDEF +123456 Expected results: ABCDEF ABCDEF+123456 Additional info:
The testcase is invalid. Please read: http://www.opengroup.org/onlinepubs/009695399/functions/sprintf.html "If copying takes place between objects that overlap as a result of a call to sprintf() or snprintf(), the results are undefined." That's the exact case here, and any result is conforming undefined behavior. ISO C99 has similar wording for this.
Aaaah - tks - audacious in Fedora Extras uses exactly this (undefined) construct and is generating bad strings. ./Plugins/Input/cdaudio/cddb.c sprintf(buffer, "%s+%d", buffer, LBA(info->track[i])); .... this is how I encountered the problem. I have referred this bug to audacious maintainer (see 216571) and upstream.