src/frontend.c

Sun, 11 Jun 2023 15:16:48 +0200

author
Mike Becker <universe@uap-core.de>
date
Sun, 11 Jun 2023 15:16:48 +0200
changeset 70
60cecca5e484
parent 67
5da2cb5aea6b
permissions
-rw-r--r--

fix illegal memory access when input file does not end with line break

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2016 Mike Becker. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  *
    28  */
    30 #include <stdio.h>
    31 #include <stdlib.h>
    32 #include <unistd.h>
    33 #include <string.h>
    35 #include "c2html.h"
    36 #include <cx/utils.h>
    38 typedef struct {
    39     char* outfilename;
    40     char* headerfile;
    41     char* footerfile;
    42     char* infilename;
    43     int showlinenumbers;
    44 } Settings;
    46 static int appendfile(const char *filename, FILE *fout, const char *errmsg) {
    47     FILE *fin = fopen(filename, "r");
    48     if (!fin) {
    49         perror(errmsg);
    50         if (fout != stdout) {
    51             fclose(fout);
    52         }
    53         return 1;
    54     }
    55     cx_stream_copy(fin, fout, (cx_read_func) fread, (cx_write_func) fwrite);
    56     fclose(fin);
    57     return 0;
    58 }
    60 static void printhelp() {
    61     printf("Formats source code using HTML.\n\nUsage:\n"
    62         "  c2html [Options] FILE\n\n"
    63         " Options:\n"
    64         "  -h                    Prints this help message\n"
    65         "  -j                    Highlight Java instead of C source code\n"
    66         "  -o <output>           Output file (stdout, if not specified)\n"
    67         "  -H <header>           Prepend header file\n"
    68         "  -F <footer>           Append footer file\n"
    69         "  -p                    Disable highlighting (plain text)\n"
    70         "  -l                    Disable line numbers\n"
    71         "  -V, -v                Prints version and exits\n"
    72         "\n");
    73 }
    75 int main(int argc, char** argv) {
    77     /* Default settings */
    78     Settings settings;
    79     memset(&settings, 0, sizeof(settings));
    80     settings.showlinenumbers = 1;
    81     c2html_highlighter_func hltr = c2html_c_highlighter;
    83     /* Parse command line */
    84     int optc;
    85     while ((optc = getopt(argc, argv, "hljo:pH:F:vV")) != -1) {
    86         switch (optc) {
    87             case 'o':
    88                 if (!(optarg[0] == '-' && optarg[1] == 0)) {
    89                     settings.outfilename = optarg;
    90                 }
    91                 break;
    92             case 'F':
    93                 settings.footerfile = optarg;
    94                 break;
    95             case 'H':
    96                 settings.headerfile = optarg;
    97                 break;
    98             case 'j':
    99                 hltr = c2html_java_highlighter;
   100                 break;
   101             case 'p':
   102                 hltr = c2html_plain_highlighter;
   103                 break;
   104             case 'l':
   105                 settings.showlinenumbers = 0;
   106                 break;
   107             case 'h':
   108                 printhelp();
   109                 return EXIT_SUCCESS;
   110             case 'v':
   111             case 'V':
   112 #ifdef VERSION_DEVELOP
   113                 printf("%d.%d (unstable)\n", VERSION_MAJOR, VERSION_MINOR);
   114 #else
   115                 printf("%d.%d\n", VERSION_MAJOR, VERSION_MINOR);
   116 #endif
   117                 return EXIT_SUCCESS;
   118             default:
   119                 return EXIT_FAILURE;
   120         }
   121     }
   123     if (optind != argc-1) {
   124         printhelp();
   125         return EXIT_FAILURE;
   126     } else {
   127         /* Open output file */
   128         settings.infilename = argv[optind];
   129         FILE *fout;
   130         if (settings.outfilename) {
   131             fout = fopen(settings.outfilename, "w");
   132             if (!fout) {
   133                 perror("Error opening output file");
   134                 return EXIT_FAILURE;
   135             }
   136         } else {
   137             fout = stdout;
   138         }
   140         /* Prepend header file */
   141         if (appendfile(settings.headerfile, fout,
   142                 "Error opening header file")) {
   143             return EXIT_FAILURE;
   144         }
   146         /* Process input file */
   147         FILE *inputfile = fopen(settings.infilename, "r");
   148         if (inputfile) {
   149             CxBuffer fbuf;
   150             cxBufferInit(&fbuf, NULL, 4096, NULL, CX_BUFFER_AUTO_EXTEND);
   151             cx_stream_copy(inputfile, &fbuf, (cx_read_func) fread,
   152                            (cx_write_func) cxBufferWrite);
   153             cxBufferPut(&fbuf, 0);
   154             fclose(inputfile);
   155             c2html_textformat(
   156                     fbuf.space, fout, (cx_write_func ) fwrite, hltr,
   157                     settings.showlinenumbers
   158             );
   159             cxBufferDestroy(&fbuf);
   160         } else {
   161             perror("Error opening input file");
   162             if (fout != stdout) {
   163                 fclose(fout);
   164             }
   165             return EXIT_FAILURE;
   166         }
   168         /* Append footer file */
   169         if (appendfile(settings.footerfile, fout,
   170                 "Error opening footer file")) {
   171             return EXIT_FAILURE;
   172         }
   174         return EXIT_SUCCESS;
   175     }
   176 }

mercurial