Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modern printf format length modifiers lead to garbage output #64

Open
LeSpocky opened this issue May 5, 2023 · 4 comments
Open

Modern printf format length modifiers lead to garbage output #64

LeSpocky opened this issue May 5, 2023 · 4 comments

Comments

@LeSpocky
Copy link

LeSpocky commented May 5, 2023

C99 introduced new length modifiers. In addition to the well known and supported 'l', 'L', and 'h' we have 'hh', 'll', 'j', 'z', and 't' now. (See https://en.cppreference.com/w/c/io/fprintf for reference for example.) Those are not supported by fcgi, however the compiler supporting C99 or newer happily allows to use them without warning. The output is cut off however at the unknown length modifier.

Code example:

#include <fcgi_stdio.h>
#include <stddef.h>

int main( int argc, char *argv[] )
{
    size_t zcntp = 0;

    while ( FCGI_Accept() >= 0 )
    {
        printf( "Content-type: text/html\r\n" 
                "\r\n" );

        puts( "<html><head><title>test fastcgi</title></head><body>" );
        printf( "<p>size_t count (printf): %zu.</p>\n", ++zcntp );
        puts( "</body></html>" );

        fprintf( stderr, "zcntp: %zu\n", zcntp );
    }

    FCGI_Finish();
    
    return 0;
}

In the printf() statement the output is cut off at the '%' and you'll never see the .</p>\n in the output. The output to stderr is also cut off like this without printing any number: "zcntp: "

@mcarbonneaux
Copy link
Member

for me is not dependant of fcgi, is dependant of the compiler you use.

@LeSpocky
Copy link
Author

for me is not dependant of fcgi, is dependant of the compiler you use.

Not really. It depends on what C dialect you instruct your compiler to use and what's the default of the compiler. Speaking of GCC, according to https://stackoverflow.com/a/14737642 and the manual C11 (implying the older C99) is default since GCC 5.5 which was released in 2017.

I would assume most C code written today uses at least some features of C99. So from my point of view a library not supporting an over 20 years old language standard, is buggy.

(FWIW, I do not expect anyone to fix this. You can consider the ticket be the public documentation of what happens, so other users can find the information and don't have to dig by themselves.)

@mcarbonneaux
Copy link
Member

mcarbonneaux commented Jun 6, 2023

is what is say, is dependent of the compiler/compiler options or define that interfere on compiler compliance.
perhaps the automake/autoconfig system used by fcgi build set bad options to the compiler...
or set some define (in includes) that interfere on C compliance of the compiler...

you tried to do something like that:

export CFLAGS="-std=c99"
export CC="gcc"

make 

cf: https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html

@LeSpocky
Copy link
Author

LeSpocky commented Jun 8, 2023

It's not about the options used to build fcgi itself. This works, I don't care about those. It is about the options I build my own application with, which I link against libfcgi then.

The special thing libfcgi does is replacing stuff by its own implementations which is usually in the libc. This is the way to go explained in fcgi documentation especially if you migrate cgi code to libfcgi. You should not include stdio.h but fcgi_stdio.h as written here: https://fastcgi-archives.github.io/fcgi2/doc/fcgi-devel-kit.htm#S3

If I build my own application with C99 or newer now (Note: this is default with any recent compiler, gcc switched to C11 by default with version 5 released back in 2015), and link that application to libfcgi, the compiler will happily do so without complaining. If I use the above mentioned C99 format specifiers in my app code, libfcgi will produce wrong results at runtime.

In other words: if I start a new webapp today and build and link it against a probably pre-built libfcgi (like libfcgi-dev from Debian) with default compiler options, I will sooner or later run into this problem.

I see several solutions to this:

  • teach libfcgi those C99 features (I guess that won't happen, the project is in no state where anyone would introduce new features, right?) 🤓
  • avoid those failing things in my own code while still building as C99 or later, this is risky because it's very easy to introduce wrong runtime behavior in my code by accident again 🙄
  • explicitly restrict my own code to pre C99 aka C89/C90 and drop all the nice things C99 has to offer 👎
  • something else, not sure what that could be, but maybe someone has a nice solution

I don't say this is easy and I don't demand a fix from anyone. However I still consider this a problem users of fcgi should be aware of. 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants