• Bug#714549: mini-httpd: literal charset=%s in error pages and directory

    From Alexander Foken@21:1/5 to All on Sun Mar 17 20:00:01 2024
    Dear Maintainer,


    I've tried to reproduce the problem in Debian sid, and it still exists.
    I've looked at the source code, and the problem should be easy to fix.

    Actually, the "charset=%s" problem are two different, but closely
    related problems.

    The entire source code contains "charset=%s" only three times:

    (1) In do_file() starting at line 1593, "charset=%s" may be returned by figure_mime() into mime_type, it is then passed to
    snprintf(fixed_mime_type, sizeof(fixed_mime_type), mime_type, charset)
    to expand %s to the default charset in fixed_mime_type, and a few lines
    below, fixed_mime_type is passed to add_headers().

    This seems to be the way that "charset=%s" was intended to be used.

    No problem here.

    (2) In do_dir() starting at line 1731, "charset=%s" is directly passed
    to add_headers(), without any call to snprintf().

    To me, this looks like a little oversight, I would gess the "charset=%s"
    was added in assuming that add_headers() would expand "%s" (which is
    does not).

    Looking up a few lines (line 1678), the generated HTML response sets the charset to UTF-8 via a META element, so it makes no sense to use any
    other charset than UTF-8 in do_dir().

    So the fix for do_dir() is simple: Replace "charset=%s" with
    "charset=UTF-8" in line 1731.

    This actually makes the META element in line 1678 redundant, so the
    entire line 1678 should be removed.

    (3) In send_error() a line 2465, add_headers() is againg called with a
    literal "charset=%s", without any call to snprintf().

    This seems to be the same little oversight as in do_dir().

    send_error() is always called with a fixed title and a fixed error
    message, and except for the call in send_authenticate() line 2431, the extra_header parameter is always empty. It is very tempting to just use
    a hardcoded "charset=UTF-8" as in do_dir(), but send_error() has one
    extra trick: It calls send_error_body(), which in turn calls
    send_error_file to handle custom error pages. They should be encoded in
    the default charset, which may be something else than UTF-8.

    So send_error() needs to follow the behaviour of do_file(): Use a buffer
    and snprintf() to expand %s to the default charset. In other words:

    Replace  starting at line 2465 ...

        add_headers(s, title, extra_header, "", "text/html; charset=%s", (off_t) -1, (time_t) -1);

    ... with ...

        char fixed_mime_type[500];
        (void) snprintf(
            fixed_mime_type, sizeof(fixed_mime_type), "text/html; charset=%s", charset );
        add_headers(
            s, title, extra_header, "", fixed_mime_type, (off_t) -1, (time_t) -1 );

    ... and remove the hardcoded META element emitted by send_error_body()
    in line 2511.


    Testing in a default installation of mini-httpd can be done from the shell:

    root@debian-sid:~# mkdir -p /var/www/html/directory
    root@debian-sid:~# echo -en 'GET /no/such/file HTTP/1.0\r\n\r\n' | nc
    127.0.0.1 80 | grep -i Content-Type
    Content-Type: text/html; charset=%s
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> root@debian-sid:~# echo -en 'GET /directory/ HTTP/1.0\r\n\r\n' | nc
    127.0.0.1 80 | grep -i Content-Type
    Content-Type: text/html; charset=%s
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8"> root@debian-sid:~#


    Best regards,

    Alexander Foken

    --

    Alexander Foken
    mailto:alexander@foken.de

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)