slweb

Једноставни генератор статичких веб страна
git clone https://git.sr.ht/~strahinja/slweb
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 145b69d2686b446f1e649fdd8b9caa456600cef5
родитељ 74d80f8ca27bf8c1b9593196ec8697add5494081
Аутор: Страхиња Радић <sr@strahinja.org>
Датум:   Mon, 15 Jul 2024 23:03:07 +0200

slweb.c: strlc{at,py} -> MEMCCPY; code cleanup

Diffstat:
Mslweb.c | 1030++++++++++++++++++++++++++++++++++++-------------------------------------------
измењених датотека: 1, додавања: 472(+), брисања: 558(-)

diff --git a/slweb.c b/slweb.c @@ -2,13 +2,34 @@ * any later version. Copyright (C) 2020-2024 Страхиња Радић. * See the file LICENSE for exact copyright and license details. */ +/* Uncomment to enable assert(3) */ +#define NDEBUG + +#include <assert.h> +#include <ctype.h> +#include <dirent.h> +#include <errno.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include "utf8.h" #include "defs.h" +#include "version.h" static size_t lineno = 0; static size_t colno = 1; static int output_firstcol = 1; -static const char* input_filename = NULL; +static char* input_filename = NULL; static char* input_dirname = NULL; +static size_t ifn_size = 0; static char* basedir = NULL; static size_t basedir_size = 0; static char* incdir = NULL; @@ -31,10 +52,12 @@ static u8** inline_footnotes = NULL; static size_t inline_footnote_count = 0; static size_t current_inline_footnote = 0; static u8* csv_template = NULL; +static size_t csv_template_len = 0; static size_t csv_template_size = 0; static char* csv_filename = NULL; static long csv_iter = 0; static u8* tsv_template = NULL; +static size_t tsv_template_len = 0; static size_t tsv_template_size = 0; static char* tsv_filename = NULL; static long tsv_iter = 0; @@ -83,7 +106,15 @@ static int incdir_only_summary = 0; if (!temp) \ to[tolen > 0 ? tolen - 1 : 0] = 0; \ } while (0) +#define MEMCCPY_EXT(to, fallbackto, from, tolen, temp) \ + do \ + { \ + temp = memccpy(to, from, 0, tolen); \ + if (!temp) \ + fallbackto[tolen > 0 ? tolen - 1 : 0] = 0; \ + } while (0) +/* Copy *pline to *ptoken and increase ptoken */ #define CHECKCOPY(token, ptoken, token_size, pline) \ do \ { \ @@ -106,7 +137,7 @@ static int incdir_only_summary = 0; ptoken = token; \ } while (0) -int slweb_cleanup(void); +int cleanup(void); int usage(void); int version(const int full); @@ -172,7 +203,7 @@ free_keyvalue(KeyValue** list, const size_t list_count) } int -slweb_cleanup(void) +cleanup(void) { free(basedir); free(input_dirname); @@ -195,8 +226,9 @@ int add_css(FILE* output, int output_yaml); u8* format_date(const u8* date_arg, const char* timestamp_format); int simple_parse_yaml_line(const u8* line, KeyValue** vars, size_t* vars_count, KeyValue** pvars); -int slweb_parse(FILE* output, const char* source_filename, const u8* buffer, - const int body_only, const int read_yaml_macros_and_links); +int slweb_parse(FILE* output, const char* source_filename, + const size_t sfn_size, const u8* buffer, const int body_only, + const int read_yaml_macros_and_links); int startswith(const char* s, const char* what) @@ -328,7 +360,7 @@ set_global_link_prefix(char** global_link_prefix, } char* -strip_ext(const char* fn) +strip_ext(const char* fn, const size_t fn_size) { char* newname = NULL; char* pnewname = NULL; @@ -340,7 +372,13 @@ strip_ext(const char* fn) if (!dot) return NULL; - CALLOC(newname, char, strlen(fn) + 1); + newname = strndup(fn, fn_size); + if (!newname) + { + perror(PROGRAMNAME ": strndup"); + exit(error(ENOMEM, __FILE__, __func__, __LINE__, + "Allocation error")); + } pnewname = newname; pfn = fn; @@ -353,11 +391,11 @@ strip_ext(const char* fn) int print_output(FILE* output, const char* fmt, ...) { - char* temp = NULL; + u8* var_incdir_only_summary = NULL; + char* temp = NULL; char buf[BUFSIZE]; va_list args; - u8* var_incdir_only_summary = NULL; - int incdir_only_summary = 0; + int incdir_only_summary = 0; if (!output || !fmt) exit(error(EINVAL, __FILE__, __func__, __LINE__, @@ -386,16 +424,14 @@ print_output(FILE* output, const char* fmt, ...) } else { - if (strlen((char*)csv_template) + buf_len - > csv_template_size) + csv_template_len = strlen((char*)csv_template); + if (csv_template_len + buf_len > csv_template_size) { csv_template_size += BUFSIZE; REALLOC(csv_template, u8, csv_template_size); } - if (strlcat((char*)csv_template, buf, csv_template_size) - > csv_template_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY((csv_template + csv_template_len), buf, + csv_template_size - csv_template_len, temp); } } else if (IN(state, ST_TSV_BODY)) @@ -411,16 +447,14 @@ print_output(FILE* output, const char* fmt, ...) } else { - if (strlen((char*)tsv_template) + buf_len - > tsv_template_size) + tsv_template_len = strlen((char*)tsv_template); + if (tsv_template_len + buf_len > tsv_template_size) { tsv_template_size += BUFSIZE; REALLOC(tsv_template, u8, tsv_template_size); } - if (strlcat((char*)tsv_template, buf, tsv_template_size) - > tsv_template_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY((tsv_template + tsv_template_len), buf, + tsv_template_size - tsv_template_len, temp); } } else @@ -626,33 +660,27 @@ process_git_log(FILE* output) if (!input_filename) return warning(1, (u8*)"Cannot use 'git-log' in stdin"); + u8* pipe_args[] = {NULL, NULL}; char* basename = NULL; + char* temp = NULL; size_t basename_size = BUFSIZE; - CALLOC(basename, char, basename_size); - char* slash = strrchr(input_filename, '/'); - pid_t result = 0; + char* slash = NULL; + pid_t result = 0; + slash = strrchr(input_filename, '/'); + CALLOC(basename, char, basename_size); if (slash) - { - if (strlcpy(basename, slash + 1, basename_size) >= basename_size) - warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__); - } + MEMCCPY(basename, slash + 1, basename_size, temp); else - { - if (strlcpy(basename, input_filename, basename_size) - >= basename_size) - warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__); - } + MEMCCPY(basename, input_filename, basename_size, temp); - u8* pipe_args[] = {(u8*)basename, NULL}; + pipe_args[0] = (u8*)basename; print_output(output, "<div id=\"git-log\">\nPrevious commit:\n"); result = print_command(output, CMD_GIT_LOG, (const u8**)CMD_GIT_LOG_ARGS, (const u8**)pipe_args, 0); - print_output(output, "</div><!--git-log-->\n"); output_firstcol = 1; - free(basename); return result ? warning(result, (u8*)"git-log: Cannot run git") : 0; @@ -888,16 +916,17 @@ tsv_template_done: int read_tsv(FILE* output, const char* filename, tsv_callback_t callback) { - FILE* tsv = NULL; - u8* bufline = NULL; - u8* pbufline = NULL; - u8* token = NULL; - u8* ptoken = NULL; + FILE* tsv = NULL; + u8* bufline = NULL; + u8* pbufline = NULL; + u8* token = NULL; + u8* ptoken = NULL; u8* tsv_header[MAX_TSV_REGISTERS]; u8* tsv_register[MAX_TSV_REGISTERS]; - size_t tsv_lineno = 0; - size_t token_size = 0; - UBYTE current_header = 0; + char* ctemp = NULL; + size_t tsv_lineno = 0; + size_t token_size = 0; + UBYTE current_header = 0; UBYTE current_register = 0; if (!callback) @@ -941,21 +970,15 @@ read_tsv(FILE* output, const char* filename, tsv_callback_t callback) if (tsv_lineno > 0 && current_register < MAX_TSV_REGISTERS) { - if (strlcpy((char*)tsv_register[current_register], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(tsv_register[current_register], + (char*)token, BUFSIZE, ctemp); current_register++; } else if (tsv_lineno <= 0 && current_header < MAX_TSV_REGISTERS) { - if (strlcpy((char*)tsv_header[current_header], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(tsv_header[current_header], + (char*)token, BUFSIZE, ctemp); current_header++; } RESET_TOKEN(token, ptoken, token_size); @@ -971,11 +994,8 @@ read_tsv(FILE* output, const char* filename, tsv_callback_t callback) { if (current_register < MAX_TSV_REGISTERS) { - if (strlcpy((char*)tsv_register[current_register], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(tsv_register[current_register], + (char*)token, BUFSIZE, ctemp); current_register++; } } @@ -983,11 +1003,8 @@ read_tsv(FILE* output, const char* filename, tsv_callback_t callback) { if (current_header < MAX_TSV_REGISTERS) { - if (strlcpy((char*)tsv_header[current_header], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(tsv_header[current_header], + (char*)token, BUFSIZE, ctemp); current_header++; } } @@ -1324,8 +1341,10 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback) UBYTE current_header = 0; u8* csv_register[MAX_CSV_REGISTERS]; UBYTE current_register = 0; - u8* csv_delimiter - = get_value(vars, vars_count, (u8*)"csv-delimiter", NULL); + u8* csv_delimiter = NULL; + char* temp = NULL; + + csv_delimiter = get_value(vars, vars_count, (u8*)"csv-delimiter", NULL); if (!(csv = fopen(filename, "rt"))) { @@ -1376,23 +1395,15 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback) if (csv_lineno > 0 && current_register < MAX_CSV_REGISTERS) { - if (strlcpy((char*)csv_register - [current_register], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(csv_register[current_register], + (char*)token, BUFSIZE, temp); current_register++; } else if (csv_lineno <= 0 && current_header < MAX_CSV_REGISTERS) { - if (strlcpy((char*)csv_header - [current_header], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(csv_header[current_header], + (char*)token, BUFSIZE, temp); current_header++; } RESET_TOKEN(token, ptoken, token_size); @@ -1408,23 +1419,15 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback) if (csv_lineno > 0 && current_register < MAX_CSV_REGISTERS) { - if (strlcpy((char*)csv_register - [current_register], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(csv_register[current_register], + (char*)token, BUFSIZE, temp); current_register++; } else if (csv_lineno <= 0 && current_header < MAX_CSV_REGISTERS) { - if (strlcpy((char*)csv_header - [current_header], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(csv_header[current_header], + (char*)token, BUFSIZE, temp); current_header++; } RESET_TOKEN(token, ptoken, token_size); @@ -1440,11 +1443,8 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback) { if (current_register < MAX_CSV_REGISTERS) { - if (strlcpy((char*)csv_register[current_register], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(csv_register[current_register], + (char*)token, BUFSIZE, temp); current_register++; } } @@ -1452,11 +1452,8 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback) { if (current_header < MAX_CSV_REGISTERS) { - if (strlcpy((char*)csv_header[current_header], - (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(csv_header[current_header], + (char*)token, BUFSIZE, temp); current_header++; } } @@ -1666,7 +1663,7 @@ process_include(FILE* output, const u8* token, state = ST_NONE; /* First pass: read YAML, macros and links */ - result = slweb_parse(output, filename, buffer, 1, 1); + result = slweb_parse(output, filename, BUFSIZE, buffer, 1, 1); add_css(child_output, 1); if (result || read_yaml_macros_and_links) @@ -1677,11 +1674,11 @@ process_include(FILE* output, const u8* token, current_inline_footnote = 0; /* Second pass: parse and output */ - result = slweb_parse(output, filename, buffer, 1, 0); + result = slweb_parse(output, filename, BUFSIZE, buffer, 1, 0); process_include_child_cleanup: fflush(output); - slweb_cleanup(); + cleanup(); free(filename); free(buffer); fclose(child_output); @@ -1806,9 +1803,10 @@ process_incdir_subdir(FILE* output, const char* subdirname, { struct dirent** namelist; struct dirent** pnamelist; - long names_total = 0; - long names_output; char* abs_subdirname = NULL; + char* temp = NULL; + long names_total = 0; + long names_output; UNUSED(link_prefix); @@ -1855,16 +1853,17 @@ process_incdir_subdir(FILE* output, const char* subdirname, FILE* input = NULL; FILE* output = stdout; u8* buffer = NULL; - size_t buffer_size = 0; - int result = 0; - ULLONG saved_state = ST_NONE; - char* filename = NULL; - char* link = NULL; - u8* title = NULL; u8* date = NULL; - u8* var_incdir_only_summary = NULL; - int incdir_only_summary = 0; u8* formatted_date = NULL; + u8* title = NULL; + u8* var_incdir_only_summary = NULL; + char* filename = NULL; + char* link = NULL; + ULLONG saved_state = ST_NONE; + size_t buffer_size = 0; + size_t link_len; + int incdir_only_summary = 0; + int result = 0; if (!strcmp(basedir, ".")) set_basedir(&basedir, &basedir_size, @@ -1872,7 +1871,7 @@ process_incdir_subdir(FILE* output, const char* subdirname, CALLOC(filename, char, BUFSIZE); snprintf(filename, BUFSIZE, "%s/%s", abs_subdirname, (*pnamelist)->d_name); - link = strip_ext(filename); + link = strip_ext(filename, BUFSIZE); read_file_into_buffer(&input, &buffer, &buffer_size, filename, &input_dirname); @@ -1899,7 +1898,8 @@ process_incdir_subdir(FILE* output, const char* subdirname, state = ST_INCDIR; /* First pass: read YAML, macros and links */ - result = slweb_parse(output, filename, buffer, 1, 1); + result = slweb_parse(output, filename, BUFSIZE, buffer, + 1, 1); if (result) { warning(1, @@ -1944,7 +1944,7 @@ process_incdir_subdir(FILE* output, const char* subdirname, } incdir_subdir_child_cleanup: - slweb_cleanup(); + cleanup(); free(formatted_date); free(link); free(filename); @@ -1961,18 +1961,20 @@ process_incdir_subdir(FILE* output, const char* subdirname, current_inline_footnote = 0; /* Second pass: parse and output */ - result = slweb_parse(output, filename, buffer, 1, 0); + result = slweb_parse(output, filename, BUFSIZE, buffer, + 1, 0); state = saved_state; if (footer_permalink_text && incdir_only_summary) { - if (ext_in_permalink - && strlcat(link, timestamp_output_ext, - sizeof link) - > sizeof link) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + if (ext_in_permalink) + { + link_len = strlen(link); + MEMCCPY((link + link_len), + timestamp_output_ext, + BUFSIZE - link_len, temp); + } /* TODO: Get rid of orphan <p> just before * <footer>; would probably need another flag @@ -1987,7 +1989,7 @@ process_incdir_subdir(FILE* output, const char* subdirname, } fflush(output); - slweb_cleanup(); + cleanup(); free(formatted_date); free(link); free(filename); @@ -2143,6 +2145,8 @@ format_date(const u8* date_arg, const char* timestamp_format) u8* formatted_date = NULL; u8* ptr = NULL; u8* date = NULL; + char* temp = NULL; + size_t formatted_date_len; date = (u8*)strdup((const char*)date_arg); if (!date) @@ -2159,35 +2163,30 @@ format_date(const u8* date_arg, const char* timestamp_format) day = (u8*)strtok_r(NULL, "T", (char**)&ptr); if (!day) goto format_date_cleanup; - ptimestamp_format = timestamp_format; + ptimestamp_format = timestamp_format; + formatted_date_len = 0; while (*ptimestamp_format) { if (*ptimestamp_format == 'd' || *ptimestamp_format == 'D') { - if (strlcat((char*)formatted_date, (char*)day, - DATEBUFSIZE) - > DATEBUFSIZE) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY((formatted_date + formatted_date_len), day, + DATEBUFSIZE - formatted_date_len, temp); + formatted_date_len += strlen((char*)day); } else if (*ptimestamp_format == 'm' || *ptimestamp_format == 'M') { - if (strlcat((char*)formatted_date, (char*)month, - DATEBUFSIZE) - > DATEBUFSIZE) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY((formatted_date + formatted_date_len), month, + DATEBUFSIZE - formatted_date_len, temp); + formatted_date_len += strlen((char*)month); } else if (*ptimestamp_format == 'y' || *ptimestamp_format == 'Y') { - if (strlcat((char*)formatted_date, (char*)year, - DATEBUFSIZE) - > DATEBUFSIZE) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY((formatted_date + formatted_date_len), year, + DATEBUFSIZE - formatted_date_len, temp); + formatted_date_len += strlen((char*)year); } else - *(formatted_date + strlen((char*)formatted_date)) + *(formatted_date + formatted_date_len++) = *ptimestamp_format; ptimestamp_format++; @@ -2237,6 +2236,8 @@ int process_macro_def(FILE* output, const u8* token, const int read_yaml_macros_and_links, const int end_tag) { + char* temp = NULL; + if (end_tag) { fflush(output); @@ -2264,9 +2265,7 @@ process_macro_def(FILE* output, const u8* token, pmacros = macros + macros_count - 1; } CALLOC(pmacros->key, u8, KEYSIZE); - if (strlcpy((char*)pmacros->key, (char*)token + 2, KEYSIZE) - >= KEYSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__); + MEMCCPY(pmacros->key, (char*)token + 2, KEYSIZE, temp); pmacros->value = NULL; pmacros->value_size = 0; } @@ -2732,12 +2731,13 @@ int process_inline_footnote(const u8* token, const int read_yaml_macros_and_links, FILE* output) { - current_inline_footnote++; + char* temp = NULL; + size_t token_len; + current_inline_footnote++; if (read_yaml_macros_and_links) { - size_t token_len = strlen((char*)token); - + token_len = strlen((char*)token); inline_footnote_count++; if (inline_footnote_count == 1 && footnote_count > 0) warning(1, @@ -2754,11 +2754,8 @@ process_inline_footnote(const u8* token, const int read_yaml_macros_and_links, CALLOC(inline_footnotes[inline_footnote_count - 1], u8, token_len + 1); - if (strlcpy((char*)inline_footnotes[inline_footnote_count - 1], - (char*)token, token_len + 1) - >= token_len + 1) - warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__); - *(inline_footnotes[inline_footnote_count - 1] + token_len) = 0; + MEMCCPY(inline_footnotes[inline_footnote_count - 1], + (char*)token, token_len + 1, temp); } else { @@ -2777,6 +2774,8 @@ int process_footnote(FILE* output, const u8* token, const int footnote_definition, const int footnote_output) { + char* temp = NULL; + current_footnote++; if (footnote_definition) @@ -2797,9 +2796,7 @@ process_footnote(FILE* output, const u8* token, const int footnote_definition, pfootnotes = footnotes + footnote_count - 1; } CALLOC(pfootnotes->key, u8, KEYSIZE); - if (strlcpy((char*)pfootnotes->key, (char*)token, KEYSIZE) - >= KEYSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__); + MEMCCPY(pfootnotes->key, (char*)token, KEYSIZE, temp); pfootnotes->value = NULL; pfootnotes->value_size = 0; } @@ -2959,12 +2956,13 @@ end_head_start_body(FILE* output) } int -begin_article(FILE* output, const char* source_filename, const u8* link_prefix, - const int add_article_header, const u8* author, const u8* title, - const u8* header_text, const char* title_heading_level, u8* date, - const int ext_in_permalink, const char* permalink_url) +begin_article(FILE* output, const char* source_filename, const size_t sfn_size, + const u8* link_prefix, const int add_article_header, const u8* author, + const u8* title, const u8* header_text, const char* title_heading_level, + u8* date, const int ext_in_permalink, const char* permalink_url) { int save_incdir = IN(state, ST_INCDIR); + char* temp = NULL; UNUSED(add_article_header); state &= ~ST_INCDIR; @@ -2986,22 +2984,24 @@ begin_article(FILE* output, const char* source_filename, const u8* link_prefix, if (date && source_filename) { - char* link = strip_ext((const char*)source_filename); - u8* permalink_macro = get_value(macros, macros_count, - (u8*)"permalink", NULL); - - if (ext_in_permalink - && strlcat(link, timestamp_output_ext, sizeof link) - > sizeof link) - warning(1, (u8*)"strlcat:%d: Overflow", __LINE__); + u8* permalink_macro = NULL; + char* link = NULL; + size_t link_len; + permalink_macro = get_value(macros, macros_count, + (u8*)"permalink", NULL); + link = strip_ext((const char*)source_filename, BUFSIZE); + assert(sfn_size != 0); + link_len = strlen(link); + if (ext_in_permalink) + MEMCCPY((link + link_len), timestamp_output_ext, + sfn_size - link_len, temp); if (permalink_url) process_timestamp(output, link_prefix, permalink_url, permalink_macro, date, ext_in_permalink); else process_timestamp(output, link_prefix, link, permalink_macro, date, ext_in_permalink); - free(link); } @@ -3082,6 +3082,7 @@ simple_parse_yaml_line(const u8* line, KeyValue** vars, size_t* vars_count, u8* ptoken = NULL; u8* var_key = NULL; const u8* pline = line; + char* temp = NULL; int in_arg = 0; if (!line || !vars || !vars_count || !pvars) @@ -3142,18 +3143,11 @@ simple_parse_yaml_line(const u8* line, KeyValue** vars, size_t* vars_count, *pvars = *vars + *vars_count - 1; } CALLOC((*pvars)->key, u8, KEYSIZE); - if (strlcpy((char*)(*pvars)->key, (char*)var_key, - KEYSIZE) - >= KEYSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY((*pvars)->key, (char*)var_key, KEYSIZE, temp); (*pvars)->value_size = strlen((char*)token) + 1; CALLOC((*pvars)->value, u8, (*pvars)->value_size); - if (strlcpy((char*)(*pvars)->value, (char*)token, - (*pvars)->value_size) - >= (*pvars)->value_size) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY((*pvars)->value, (char*)token, + (*pvars)->value_size, temp); } } free(var_key); @@ -3162,8 +3156,9 @@ simple_parse_yaml_line(const u8* line, KeyValue** vars, size_t* vars_count, } int -slweb_parse(FILE* output, const char* source_filename, const u8* buffer, - const int body_only, const int read_yaml_macros_and_links) +slweb_parse(FILE* output, const char* source_filename, const size_t sfn_size, + const u8* buffer, const int body_only, + const int read_yaml_macros_and_links) { u8* title = NULL; u8* title_heading_level = NULL; @@ -3185,12 +3180,18 @@ slweb_parse(FILE* output, const char* source_filename, const u8* buffer, u8* pline = NULL; size_t line_len = 0; size_t line_size = 0; + size_t entity_len = 0; + size_t tag_len = 0; u8* token = NULL; u8* ptoken = NULL; size_t token_size = 0; + size_t token_len = 0; + size_t value_len = 0; u8* link_text = NULL; size_t link_size = 0; u8* link_macro = NULL; + u8* temp = NULL; + u8* temp2 = NULL; UBYTE heading_level = 0; ULONG heading_count = 0; int break_mark = 0; @@ -3265,7 +3266,7 @@ slweb_parse(FILE* output, const char* source_filename, const u8* buffer, } if (!read_yaml_macros_and_links) - begin_article(output, source_filename, link_prefix, + begin_article(output, source_filename, sfn_size, link_prefix, var_add_article_header && *var_add_article_header == '1', author, title, header_text, (char*)title_heading_level, date, ext_in_permalink && *ext_in_permalink != '0', @@ -3402,10 +3403,7 @@ do_line: pvars = vars + vars_count - 1; } CALLOC(pvars->key, u8, KEYSIZE); - if (strlcpy((char*)pvars->key, (char*)token, KEYSIZE) - >= KEYSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(pvars->key, (char*)token, KEYSIZE, temp); pvars->value = NULL; pvars->value_size = 0; @@ -3449,20 +3447,15 @@ do_line: ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { - size_t entity_len = strlen((char*)entity); - size_t token_len = 0; - - *ptoken = 0; - token_len = strlen((char*)token); - + entity_len = strlen((char*)entity); + *ptoken = 0; + token_len = strlen((char*)token); if (token_len + entity_len < BUFSIZE) { - if (strlcat((char*)token, (char*)entity, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += entity_len; + MEMCCPY((token + token_len), entity, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -3494,20 +3487,15 @@ do_line: ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { - size_t entity_len = strlen((char*)entity); - size_t token_len = 0; - - *ptoken = 0; - token_len = strlen((char*)token); - + entity_len = strlen((char*)entity); + *ptoken = 0; + token_len = strlen((char*)token); if (token_len + entity_len < BUFSIZE) { - if (strlcat((char*)token, (char*)entity, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += entity_len; + MEMCCPY((token + token_len), entity, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -3538,22 +3526,17 @@ do_line: ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { - u8* tag = IN(state, ST_STRIKE) ? (u8*)"</s>" - : (u8*)"<s>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - + u8* tag = IN(state, ST_STRIKE) ? (u8*)"</s>" + : (u8*)"<s>"; + tag_len = strlen((char*)tag); *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len < BUFSIZE) { - if (strlcat((char*)token, (char*)tag, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -3624,22 +3607,17 @@ do_line: ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { - u8* tag = IN(state, ST_CODE) ? (u8*)"</code>" - : (u8*)"<code>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - + u8* tag = IN(state, ST_CODE) ? (u8*)"</code>" + : (u8*)"<code>"; + tag_len = strlen((char*)tag); *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len < BUFSIZE) { - if (strlcat((char*)token, (char*)tag, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -3737,20 +3715,15 @@ do_line: { u8* tag = IN(state, ST_BOLD) ? (u8*)"</strong>" : (u8*)"<strong>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - - *ptoken = 0; + tag_len = strlen((char*)tag); + *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len < BUFSIZE) { - if (strlcat((char*)token, (char*)tag, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -3782,22 +3755,17 @@ do_line: ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { - u8* tag = IN(state, ST_ITALIC) ? (u8*)"</em>" - : (u8*)"<em>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - + u8* tag = IN(state, ST_ITALIC) ? (u8*)"</em>" + : (u8*)"<em>"; + tag_len = strlen((char*)tag); *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len < BUFSIZE) { - if (strlcat((char*)token, (char*)tag, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -3942,20 +3910,15 @@ do_line: { u8* tag = IN(state, ST_BOLD) ? (u8*)"</strong>" : (u8*)"<strong>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - - *ptoken = 0; + tag_len = strlen((char*)tag); + *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len < BUFSIZE) { - if (strlcat((char*)token, (char*)tag, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -3988,22 +3951,17 @@ do_line: | ST_FOOTNOTE_TEXT | ST_LINK)) { - u8* tag = IN(state, ST_ITALIC) ? (u8*)"</em>" - : (u8*)"<em>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - + u8* tag = IN(state, ST_ITALIC) ? (u8*)"</em>" + : (u8*)"<em>"; + tag_len = strlen((char*)tag); *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len < BUFSIZE) { - if (strlcat((char*)token, (char*)tag, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -4075,14 +4033,11 @@ do_line: if (strlen((char*)pline) == 2 && *(pline + 1) == ' ') { - size_t br_len = strlen("<br>"); - *ptoken = 0; - if (strlcat((char*)ptoken, "<br>", - token_size - (ptoken - token)) - > token_size - (ptoken - token)) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += br_len; + size_t ptoken_len = strlen((char*)ptoken); + *ptoken = 0; + MEMCCPY((ptoken + ptoken_len), "<br>", + token_size - ptoken_len, temp); + ptoken = temp ? temp - 1 : &token[token_size - 1]; output_firstcol = 0; pline += 2; colno++; @@ -4090,10 +4045,7 @@ do_line: else if (IN(state, ST_LINK_MACRO)) { *ptoken = 0; - if (strlcpy((char*)link_macro, (char*)token, BUFSIZE) - >= BUFSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(link_macro, (char*)token, BUFSIZE, temp); *(link_macro + strlen((char*)token)) = 0; RESET_TOKEN(token, ptoken, token_size); state &= ~ST_LINK_MACRO; @@ -4114,65 +4066,54 @@ do_line: break; } - if (IN(state, ST_MACRO_BODY)) - { - *ptoken = 0; - size_t token_len = strlen((char*)token); + if (!IN(state, ST_MACRO_BODY)) + goto parse_lbrace_not_macro; - skip_eol = 1; - if (read_yaml_macros_and_links) + *ptoken = 0; + token_len = strlen((char*)token); + skip_eol = 1; + if (read_yaml_macros_and_links) + { + if (!macros) { - if (!macros) - { - macros_count = 1; - CALLOC(macros, KeyValue, macros_count); - pmacros = macros; - } - if (pmacros->value) - { - size_t value_len - = strlen((char*)pmacros->value); + macros_count = 1; + CALLOC(macros, KeyValue, macros_count); + pmacros = macros; + } + if (pmacros->value) + { + size_t value_len + = strlen((char*)pmacros->value); - if (pmacros->value_size - < value_len + token_len + 1) - { - pmacros->value_size - += token_len; - REALLOC(pmacros->value, u8, - pmacros->value_size); - } - if (strlcat((char*)pmacros->value, - (char*)token, - pmacros->value_size) - > pmacros->value_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - } - else + if (pmacros->value_size + < value_len + token_len + 1) { - pmacros->value_size = token_len + 1; - CALLOC(pmacros->value, u8, + pmacros->value_size += token_len; + REALLOC(pmacros->value, u8, pmacros->value_size); - if (strlcpy((char*)pmacros->value, - (char*)token, - pmacros->value_size) - >= pmacros->value_size) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); } + MEMCCPY((pmacros->value + value_len), token, + pmacros->value_size - value_len, temp); + } + else + { + pmacros->value_size = token_len + 1; + CALLOC(pmacros->value, u8, pmacros->value_size); + MEMCCPY(pmacros->value, (char*)token, + pmacros->value_size, temp); } } - else - { - /* Output existing text up to { */ - process_text_token(output, line, link_prefix, - first_line_in_doc, previous_line_blank, - &previous_line_block, processed_start_of_line, - read_yaml_macros_and_links, list_para, &token, - &ptoken, &token_size, 0, 1); - processed_start_of_line = 1; - } + goto parse_lbrace_end; + + parse_lbrace_not_macro: + /* Output existing text up to { */ + process_text_token(output, line, link_prefix, first_line_in_doc, + previous_line_blank, &previous_line_block, + processed_start_of_line, read_yaml_macros_and_links, + list_para, &token, &ptoken, &token_size, 0, 1); + processed_start_of_line = 1; + parse_lbrace_end: state |= ST_TAG; RESET_TOKEN(token, ptoken, token_size); @@ -4238,13 +4179,9 @@ do_line: if (IN(state, ST_MACRO_BODY) && !(end_tag && startswith((const char*)token, "="))) { - size_t token_len; - size_t value_len; - if (read_yaml_macros_and_links) { token_len = strlen((char*)token); - skip_eol = 1; value_len = strlen((char*)pmacros->value); @@ -4335,22 +4272,17 @@ do_line: ST_INLINE_FOOTNOTE | ST_HEADING | ST_FOOTNOTE_TEXT | ST_LINK)) { - u8* tag = IN(state, ST_KBD) ? (u8*)"</kbd>" - : (u8*)"<kbd>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - + u8* tag = IN(state, ST_KBD) ? (u8*)"</kbd>" + : (u8*)"<kbd>"; + tag_len = strlen((char*)tag); *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len + 1 < token_size) { - if (strlcat((char*)token, (char*)tag, - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } } else @@ -4547,13 +4479,11 @@ do_line: if (ANY(state, ST_CODE | ST_KBD | ST_PRE)) { - size_t lt_len = strlen("&lt;"); *ptoken = 0; - if (strlcat((char*)token, "&lt;", token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += lt_len; + token_len = strlen((char*)token); + MEMCCPY((token + token_len), "&lt;", + token_size - token_len, temp); + ptoken = temp ? temp - 1 : &token[token_size - 1]; pline++; colno++; break; @@ -4732,20 +4662,16 @@ do_line: if (*pline == '(') { - u8* tag = (u8*)"<span>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - + u8* tag = (u8*)"<span>"; + tag_len = strlen((char*)tag); *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len < BUFSIZE) { - if (strlcat((char*)token, (char*)tag, token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } state |= ST_LINK_SPAN; @@ -4764,22 +4690,17 @@ do_line: CHECKCOPY(token, ptoken, token_size, pline); else if (*link_macro && (IN(state, ST_LINK))) { - u8* tag = (u8*)"<span>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - + u8* tag = (u8*)"<span>"; + tag_len = strlen((char*)tag); *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len + 1 < token_size) { - if (strlcat((char*)token, (char*)tag, token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } - state |= ST_LINK_SPAN; pline++; } @@ -4803,20 +4724,16 @@ do_line: if (IN(state, ST_LINK_SPAN) && pline_len > 1 && *(pline + 1) == ']') { - u8* tag = (u8*)"</span>"; - size_t tag_len = strlen((char*)tag); - size_t token_len = 0; - + u8* tag = (u8*)"</span>"; + tag_len = strlen((char*)tag); *ptoken = 0; token_len = strlen((char*)token); - if (token_len + tag_len + 1 < token_size) { - if (strlcat((char*)token, (char*)tag, token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += tag_len; + MEMCCPY((token + token_len), tag, + token_size - token_len, temp); + ptoken = temp ? temp - 1 + : &token[token_size - 1]; } state &= ~ST_LINK_SPAN; pline++; @@ -4942,7 +4859,6 @@ do_line: } else if (strlen((char*)pline) > 1) { - size_t token_len = 0; switch (*(pline + 1)) { case ':': @@ -4966,11 +4882,8 @@ do_line: plinks = links + links_count - 1; } CALLOC(plinks->key, u8, KEYSIZE); - if (strlcpy((char*)plinks->key, (char*)token, - KEYSIZE) - >= KEYSIZE) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(plinks->key, (char*)token, KEYSIZE, + temp); plinks->value = NULL; plinks->value_size = 0; pline += 2; @@ -4999,12 +4912,8 @@ do_line: link_size = token_len + 1; CALLOC(link_text, u8, link_size); } - if (strlcpy((char*)link_text, (char*)token, - link_size) - >= link_size) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); - *(link_text + token_len) = 0; + MEMCCPY(link_text, (char*)token, link_size, + temp); pline += 2; colno += 2; RESET_TOKEN(token, ptoken, token_size); @@ -5237,13 +5146,11 @@ do_line: case '"': if (ANY(state, ST_CODE | ST_KBD | ST_PRE)) { - size_t quot_len = strlen("&quot;"); *ptoken = 0; - if (strlcat((char*)token, "&quot;", token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += quot_len; + token_len = strlen((char*)token); + MEMCCPY((token + token_len), "&quot;", + token_size - token_len, temp); + ptoken = temp ? temp - 1 : &token[token_size - 1]; pline++; } else @@ -5256,13 +5163,11 @@ do_line: if (ANY(state, ST_CODE | ST_KBD | ST_PRE) || !*(pline + 1) || isspace(*(pline + 1))) { - size_t quot_len = strlen("&amp;"); *ptoken = 0; - if (strlcat((char*)token, "&amp;", token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - ptoken += quot_len; + token_len = strlen((char*)token); + MEMCCPY((token + token_len), "&amp;", + token_size - token_len, temp); + ptoken = temp ? temp - 1 : &token[token_size - 1]; pline++; } else @@ -5291,9 +5196,7 @@ done_line: } pvars->value_size = strlen((char*)token) + 1; CALLOC(pvars->value, u8, pvars->value_size); - if (strlcpy((char*)pvars->value, (char*)token, pvars->value_size) - >= pvars->value_size) - warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__); + MEMCCPY(pvars->value, (char*)token, pvars->value_size, temp); } else if (keep_token) { @@ -5304,11 +5207,10 @@ done_line: REALLOC(token, u8, token_size); ptoken = token + old_size - 1; } - if (strlcat((char*)token, - ANY(state, ST_IMAGE | ST_LINK) ? " " : "\n", - token_size) - > token_size) - warning(1, (u8*)"strlcat:%d: Overflow", __LINE__); + token_len = strlen((char*)token); + MEMCCPY((token + token_len), + ANY(state, ST_IMAGE | ST_LINK) ? " " : "\n", + token_size - token_len, temp); ptoken++; *ptoken = 0; } @@ -5316,8 +5218,8 @@ done_line: { if (*token) { - *ptoken = 0; - size_t token_len = strlen((char*)token); + *ptoken = 0; + token_len = strlen((char*)token); if (IN(state, ST_MACRO_BODY)) { skip_eol = 1; @@ -5341,34 +5243,34 @@ done_line: REALLOC(pmacros->value, u8, pmacros->value_size); } - if (strlcat((char*)pmacros->value, - (char*)token, - pmacros->value_size) - > pmacros->value_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - if (strlcat((char*)pmacros->value, "\n", - pmacros->value_size) - > pmacros->value_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY((pmacros->value + value_len), + token, + pmacros->value_size - value_len, + temp); + value_len += token_len; + if (temp) + MEMCCPY_EXT((temp - 1), + pmacros->value, "\n", + pmacros->value_size + - value_len, + temp2); } else { pmacros->value_size = BUFSIZE; CALLOC(pmacros->value, u8, pmacros->value_size); - if (strlcpy((char*)pmacros->value, - (char*)token, - pmacros->value_size) - >= pmacros->value_size) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); - if (strlcat((char*)pmacros->value, "\n", - pmacros->value_size) - > pmacros->value_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY(pmacros->value, (char*)token, + pmacros->value_size, temp); + if (!temp) + goto skip_macro_cat; + MEMCCPY_EXT((temp - 1), pmacros->value, + "\n", + pmacros->value_size + - ((u8*)temp + - pmacros->value), + temp2); + skip_macro_cat:; } skip_macro_read:; } @@ -5397,34 +5299,35 @@ done_line: REALLOC(pfootnotes->value, u8, pfootnotes->value_size); } - if (strlcat((char*)pfootnotes->value, - (char*)token, - pfootnotes->value_size) - > pfootnotes->value_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - if (strlcat((char*)pfootnotes->value, - "\n", pfootnotes->value_size) - > pfootnotes->value_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY((pfootnotes->value + value_len), + token, + pfootnotes->value_size + - value_len, + temp); + if (temp) + MEMCCPY_EXT((temp - 1), + (pfootnotes->value + + value_len), + "\n", + pfootnotes->value_size + - value_len, + temp2); } else { pfootnotes->value_size = BUFSIZE; CALLOC(pfootnotes->value, u8, pfootnotes->value_size); - if (strlcpy((char*)pfootnotes->value, - (char*)token, - pfootnotes->value_size) - >= pfootnotes->value_size) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); - if (strlcat((char*)pfootnotes->value, - "\n", pfootnotes->value_size) - > pfootnotes->value_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY(pfootnotes->value, token, + pfootnotes->value_size, temp); + if (temp) + MEMCCPY_EXT((temp - 1), + (pfootnotes->value + + value_len), + "\n", + pfootnotes->value_size + - value_len, + temp2); } *token = 0; ptoken = token; @@ -5447,12 +5350,8 @@ done_line: = strlen((char*)token) + 1; CALLOC(plinks->value, u8, plinks->value_size); - if (strlcpy((char*)plinks->value, - (char*)token, - plinks->value_size) - >= plinks->value_size) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(plinks->value, (char*)token, + plinks->value_size, temp); } } else if (IN(state, ST_HEADING)) @@ -5514,11 +5413,9 @@ done_line: if (!*pbuffer && (IN(state, ST_FOOTNOTE_TEXT))) { state &= ~ST_FOOTNOTE_TEXT; - - *ptoken = 0; - size_t token_len = strlen((char*)token); - - skip_eol = 1; + *ptoken = 0; + token_len = strlen((char*)token); + skip_eol = 1; if (!read_yaml_macros_and_links) goto skip_footnote_text_read; if (!footnotes) @@ -5542,24 +5439,17 @@ done_line: REALLOC(pfootnotes->value, u8, pfootnotes->value_size); } - if (strlcat((char*)pfootnotes->value, - (char*)token, - pfootnotes->value_size) - > pfootnotes->value_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); + MEMCCPY((pfootnotes->value + token_len), + token, pfootnotes->value_size + - token_len, temp); } else { pfootnotes->value_size = token_len + 1; CALLOC(pfootnotes->value, u8, pfootnotes->value_size); - if (strlcpy((char*)pfootnotes->value, - (char*)token, - pfootnotes->value_size) - >= pfootnotes->value_size) - warning(1, (u8*)"strlcpy:%d: Overflow", - __LINE__); + MEMCCPY(pfootnotes->value, (char*)token, + pfootnotes->value_size, temp); } *token = 0; ptoken = token; @@ -5655,14 +5545,16 @@ done_buffer: int main(const int argc, const char** argv) { + FILE* input = NULL; + FILE* output = stdout; + u8* buffer = NULL; + u8* eol = NULL; const char* arg; + char* temp = NULL; Command cmd = CMD_NONE; + size_t buffer_size = 0; int body_only = 0; int result = 0; - FILE* input = NULL; - FILE* output = stdout; - u8* buffer = NULL; - size_t buffer_size = 0; UNUSED(argc); basedir_size = 2; @@ -5691,7 +5583,7 @@ main(const int argc, const char** argv) result = set_basedir(&basedir, &basedir_size, arg); if (result) - return result; + exit(result); } else if (startswith(arg, "global-link-prefix")) { @@ -5700,16 +5592,16 @@ main(const int argc, const char** argv) &global_link_prefix, &global_link_prefix_size, arg); if (result) - return result; + exit(result); } else if (!strcmp(arg, "help")) - return usage(); + exit(usage()); else { error(EINVAL, __FILE__, __func__, __LINE__, "Invalid argument: --%s", arg); - return usage(); + exit(usage()); } } else @@ -5723,7 +5615,7 @@ main(const int argc, const char** argv) cmd = CMD_BASEDIR; break; case 'h': - return usage(); + exit(usage()); break; case 'p': cmd = CMD_LINK_PREFIX; @@ -5746,78 +5638,103 @@ main(const int argc, const char** argv) { int result; - if (cmd == CMD_BASEDIR) + switch (cmd) { + case CMD_BASEDIR: result = set_basedir(&basedir, &basedir_size, arg); if (result) - return result; - } - else if (cmd == CMD_LINK_PREFIX) - { + exit(result); + break; + case CMD_LINK_PREFIX: result = set_global_link_prefix(&global_link_prefix, &global_link_prefix_size, arg); if (result) - return result; + exit(result); + break; + default: + ifn_size = BUFSIZE; + CALLOC(input_filename, char, ifn_size); + MEMCCPY(input_filename, arg, ifn_size, temp); } - else - input_filename = arg; cmd = CMD_NONE; } } - if (cmd == CMD_BASEDIR) - return error(1, __FILE__, __func__, __LINE__, - "Argument required"); - - if (cmd == CMD_FULL_VERSION) - return version(1); - else if (cmd == CMD_VERSION) - return version(0); + switch (cmd) + { + case CMD_BASEDIR: + exit(error(1, __FILE__, __func__, __LINE__, + "Argument required")); + case CMD_FULL_VERSION: + version(1); + exit(0); + case CMD_VERSION: + version(0); + exit(0); + default:; + } if (input_filename) { - int result = read_file_into_buffer(&input, &buffer, - &buffer_size, input_filename, &input_dirname); + result = read_file_into_buffer(&input, &buffer, &buffer_size, + input_filename, &input_dirname); if (result) exit(result); } else { - u8* bufline = NULL; - size_t buffer_len = 0; - size_t buffer_size = 0; - size_t bufline_len = 0; + u8* bufline = NULL; + u8* pbufline = NULL; + size_t buffer_len = 0; + size_t buffer_size = 0; + size_t bufline_len = 0; + size_t bufline_size = 0; input = stdin; CALLOC(input_dirname, char, 2); *input_dirname = '.'; - CALLOC(bufline, u8, BUFSIZE); + bufline_size = BUFSIZE; + CALLOC(bufline, u8, bufline_size); buffer_size = BUFSIZE; - CALLOC(buffer, u8, buffer_size); + CALLOC(buffer, u8, buffer_size); /* freed in slweb_cleanup */ + pbufline = bufline; + + do_input: + if (feof(input)) + goto done_input; + + if (!fgets((char*)pbufline, bufline_size - (pbufline - bufline), + input)) + goto done_input; - while (!feof(input)) + eol = (u8*)strchr((char*)pbufline, '\n'); + if (eol) + *(eol + 1) = 0; /* slweb_parse will look for newline */ + else { - u8* eol = NULL; - if (!fgets((char*)bufline, BUFSIZE - 1, input)) - break; - eol = (u8*)strchr((char*)bufline, '\n'); - if (eol) - *(eol + 1) = 0; - bufline_len = strlen((char*)bufline); - if (buffer_len + bufline_len + 1 > buffer_size) - { - buffer_size += BUFSIZE; - REALLOC(buffer, u8, buffer_size); - } - if (strlcat((char*)buffer, (char*)bufline, buffer_size) - > buffer_size) - warning(1, (u8*)"strlcat:%d: Overflow", - __LINE__); - buffer_len += bufline_len; + bufline_size += BUFSIZE; + REALLOC(bufline, u8, bufline_size); + pbufline = bufline + bufline_size - BUFSIZE - 1; + goto do_input; } + + /* bufline is done, add it to buffer */ + bufline_len = strlen((char*)bufline); + if (buffer_len + bufline_len + 1 > buffer_size) + { + buffer_size += BUFSIZE; + REALLOC(buffer, u8, buffer_size); + } + + MEMCCPY((buffer + buffer_len), bufline, + buffer_size - buffer_len, temp); + buffer_len += bufline_len; + goto do_input; + + done_input: free(bufline); } @@ -5833,24 +5750,21 @@ main(const int argc, const char** argv) inline_footnote_count = 0; /* First pass: read YAML, macros and links */ - result = slweb_parse(output, input_filename, buffer, body_only, 1); - - if (result) - { - slweb_cleanup(); - free(buffer); - return result; - } + if ((result = slweb_parse(output, input_filename, ifn_size, buffer, + body_only, 1))) + goto slweb_cleanup; state = ST_NONE; current_footnote = 0; current_inline_footnote = 0; /* Second pass: parse and output */ - result = slweb_parse(output, input_filename, buffer, body_only, 0); + if ((result = slweb_parse(output, input_filename, ifn_size, buffer, + body_only, 0))) + goto slweb_cleanup; - slweb_cleanup(); +slweb_cleanup: + cleanup(); free(buffer); - return result; }