чување f5c4a5db82f0d6bd47af671f62a738c92835be5e
родитељ ffebc77bebfa9c0a3447cd0ee35cb547e3dda432
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Fri, 23 Feb 2024 15:22:48 +0100
Update copyright dates; switch to OpenBSD strlcat,strlcpy,snprintf
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
измењених датотека: 10, додавања: 478(+), брисања: 108(-)
diff --git a/README b/README
@@ -44,7 +44,7 @@ License
-------
slweb - Simple static website generator.
-Copyright (C) 2020-2023 Страхиња Радић
+Copyright (C) 2020-2024 Страхиња Радић
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
diff --git a/TODO b/TODO
@@ -6,7 +6,7 @@ TODO
[/] Real solution (children die with parent)
- Is there actually any need?
-[ ] Switch to strlcpy/strlcat
+[x] Switch to strlcpy/strlcat
[ ] Switch to POSIX make
diff --git a/defs.h b/defs.h
@@ -1,5 +1,5 @@
/* This program is licensed under the terms of GNU GPL v3 or (at your option)
- * any later version. Copyright (C) 2020-2023 Страхиња Радић.
+ * any later version. Copyright (C) 2020-2024 Страхиња Радић.
* See the file LICENSE for exact copyright and license details. */
#ifndef __DEFS_H
@@ -19,6 +19,13 @@
#include <sys/wait.h>
#include <unistd.h>
+#ifndef strlcpy
+size_t strlcpy(char *dst, const char *src, size_t dsize);
+#endif
+#ifndef strlcat
+size_t strlcat(char *dst, const char *src, size_t dsize);
+#endif
+
#include "version.h"
#include "utf8.h"
diff --git a/slweb.1.in b/slweb.1.in
@@ -36,7 +36,7 @@ slweb \- Simple static website generator
.YS
.
.SH COPYRIGHT
-slweb Copyright \(co 2020, 2021, 2022, 2023 Strahinya Radich.
+slweb Copyright \(co 2020\-2024 Strahinya Radich.
.br
This program is licensed under GNU GPL v3 or later. See the file
.I LICENSE
diff --git a/slweb.c b/slweb.c
@@ -1,5 +1,5 @@
/* This program is licensed under the terms of GNU GPL v3 or (at your option)
- * any later version. Copyright (C) 2020-2023 Страхиња Радић.
+ * any later version. Copyright (C) 2020-2024 Страхиња Радић.
* See the file LICENSE for exact copyright and license details. */
#include "defs.h"
@@ -272,7 +272,9 @@ set_basedir(char** basedir, size_t* basedir_size, const char* arg)
*basedir_size = arg_len + 1;
REALLOC(*basedir, char, *basedir_size);
}
- strcpy(*basedir, arg);
+
+ if (strlcpy(*basedir, arg, *basedir_size) > *basedir_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__);
basedir_len = strlen(*basedir);
if (*(*basedir + basedir_len - 1) == '/')
*(*basedir + basedir_len - 1) = 0;
@@ -294,7 +296,9 @@ set_global_link_prefix(char** global_link_prefix,
*global_link_prefix_size = arg_len + 1;
REALLOC(*global_link_prefix, char, *global_link_prefix_size);
}
- strcpy(*global_link_prefix, arg);
+ if (strlcpy(*global_link_prefix, arg, *global_link_prefix_size)
+ > *global_link_prefix_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__);
*(*global_link_prefix + arg_len) = 0;
return 0;
@@ -353,7 +357,10 @@ print_output(FILE* output, const char* fmt, ...)
{
csv_template_size = BUFSIZE;
CALLOC(csv_template, u8, csv_template_size);
- strcpy((char*)csv_template, buf);
+ if (strlcpy((char*)csv_template, buf, csv_template_size)
+ > csv_template_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
}
else
{
@@ -363,7 +370,10 @@ print_output(FILE* output, const char* fmt, ...)
csv_template_size += BUFSIZE;
REALLOC(csv_template, u8, csv_template_size);
}
- strcat((char*)csv_template, buf);
+ if (strlcat((char*)csv_template, buf, csv_template_size)
+ > csv_template_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
}
}
else if (IN(state, ST_TSV_BODY))
@@ -375,7 +385,10 @@ print_output(FILE* output, const char* fmt, ...)
{
tsv_template_size = BUFSIZE;
CALLOC(tsv_template, u8, tsv_template_size);
- strcpy((char*)tsv_template, buf);
+ if (strlcpy((char*)tsv_template, buf, tsv_template_size)
+ > tsv_template_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
}
else
{
@@ -385,7 +398,10 @@ print_output(FILE* output, const char* fmt, ...)
tsv_template_size += BUFSIZE;
REALLOC(tsv_template, u8, tsv_template_size);
}
- strcat((char*)tsv_template, buf);
+ if (strlcat((char*)tsv_template, buf, tsv_template_size)
+ > tsv_template_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
}
}
else
@@ -585,9 +601,16 @@ process_git_log(FILE* output)
pid_t result = 0;
if (slash)
- strcpy(basename, slash + 1);
+ {
+ if (strlcpy(basename, slash + 1, basename_size) > basename_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__);
+ }
else
- strcpy(basename, input_filename);
+ {
+ if (strlcpy(basename, input_filename, basename_size)
+ > basename_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__);
+ }
u8* pipe_args[] = {(u8*)basename, NULL};
@@ -632,7 +655,10 @@ process_inline_stylesheet(FILE* output, const u8* css_filename, int output_yaml)
css_pathname_size = basedir_size + css_filename_len + 1;
CALLOC(css_pathname, char, css_pathname_size);
- sprintf(css_pathname, "%s/%s", basedir, css_filename);
+ if (snprintf(css_pathname, css_pathname_size, "%s/%s", basedir,
+ css_filename)
+ > css_pathname_size)
+ warning(1, (u8*)"snprintf:%d: Overflow", __LINE__);
if (!(css = fopen((const char*)css_pathname, "rt")))
exit(error(ENOENT,
(u8*)"process_inline_stylesheet: No such file: %s",
@@ -852,7 +878,8 @@ read_tsv(FILE* output, const char* filename, tsv_callback_t callback)
while (!feof(tsv) && (!tsv_iter || tsv_lineno <= tsv_iter))
{
- u8* eol = NULL;
+ u8* eol = NULL;
+ size_t res = 0;
if (!fgets((char*)bufline, BUFSIZE, tsv))
break;
eol = (u8*)strchr((char*)bufline, '\n');
@@ -871,12 +898,25 @@ read_tsv(FILE* output, const char* filename, tsv_callback_t callback)
*ptoken = 0;
if (tsv_lineno > 0
&& current_register < MAX_TSV_REGISTERS)
- strcpy((char*)tsv_register[current_register++],
- (char*)token);
+ {
+ if ((res = strlcpy((char*)tsv_register
+ [current_register],
+ (char*)token, BUFSIZE))
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_register++;
+ }
else if (tsv_lineno <= 0
&& current_header < MAX_TSV_REGISTERS)
- strcpy((char*)tsv_header[current_header++],
- (char*)token);
+ {
+ if (strlcpy((char*)tsv_header[current_header],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_header++;
+ }
RESET_TOKEN(token, ptoken, token_size);
pbufline++;
break;
@@ -889,14 +929,26 @@ read_tsv(FILE* output, const char* filename, tsv_callback_t callback)
if (tsv_lineno > 0)
{
if (current_register < MAX_TSV_REGISTERS)
- strcpy((char*)tsv_register[current_register++],
- (char*)token);
+ {
+ if (strlcpy((char*)tsv_register[current_register],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_register++;
+ }
}
else
{
if (current_header < MAX_TSV_REGISTERS)
- strcpy((char*)tsv_header[current_header++],
- (char*)token);
+ {
+ if (strlcpy((char*)tsv_header[current_header],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_header++;
+ }
}
RESET_TOKEN(token, ptoken, token_size);
@@ -1201,13 +1253,26 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback)
*ptoken = 0;
if (csv_lineno > 0
&& current_register < MAX_CSV_REGISTERS)
- strcpy((char*)csv_register
- [current_register++],
- (char*)token);
+ {
+ if (strlcpy((char*)csv_register
+ [current_register],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_register++;
+ }
else if (csv_lineno <= 0
&& current_header < MAX_CSV_REGISTERS)
- strcpy((char*)csv_header[current_header++],
- (char*)token);
+ {
+ if (strlcpy((char*)csv_header
+ [current_header],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_header++;
+ }
RESET_TOKEN(token, ptoken, token_size);
pbufline++;
}
@@ -1220,13 +1285,26 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback)
*ptoken = 0;
if (csv_lineno > 0
&& current_register < MAX_CSV_REGISTERS)
- strcpy((char*)csv_register
- [current_register++],
- (char*)token);
+ {
+ if (strlcpy((char*)csv_register
+ [current_register],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_register++;
+ }
else if (csv_lineno <= 0
&& current_header < MAX_CSV_REGISTERS)
- strcpy((char*)csv_header[current_header++],
- (char*)token);
+ {
+ if (strlcpy((char*)csv_header
+ [current_header],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_header++;
+ }
RESET_TOKEN(token, ptoken, token_size);
pbufline++;
}
@@ -1239,14 +1317,26 @@ read_csv(FILE* output, const char* filename, csv_callback_t callback)
if (csv_lineno > 0)
{
if (current_register < MAX_CSV_REGISTERS)
- strcpy((char*)csv_register[current_register++],
- (char*)token);
+ {
+ if (strlcpy((char*)csv_register[current_register],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_register++;
+ }
}
else
{
if (current_header < MAX_CSV_REGISTERS)
- strcpy((char*)csv_header[current_header++],
- (char*)token);
+ {
+ if (strlcpy((char*)csv_header[current_header],
+ (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
+ current_header++;
+ }
}
RESET_TOKEN(token, ptoken, token_size);
@@ -1742,8 +1832,12 @@ process_incdir_subdir(FILE* output, const char* subdirname,
if (footer_permalink_text && incdir_only_summary)
{
- if (ext_in_permalink)
- strcat(link, timestamp_output_ext);
+ if (ext_in_permalink
+ && strlcat(link, timestamp_output_ext,
+ sizeof link)
+ > sizeof link)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
/* TODO: Get rid of orphan <p> just before
* <footer>; would probably need another flag
@@ -1929,11 +2023,29 @@ format_date(const u8* date_arg, const char* timestamp_format)
while (*ptimestamp_format)
{
if (*ptimestamp_format == 'd' || *ptimestamp_format == 'D')
- strcat((char*)formatted_date, (char*)day);
+ {
+ if (strlcat((char*)formatted_date, (char*)day,
+ DATEBUFSIZE)
+ > DATEBUFSIZE)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
+ }
else if (*ptimestamp_format == 'm' || *ptimestamp_format == 'M')
- strcat((char*)formatted_date, (char*)month);
+ {
+ if (strlcat((char*)formatted_date, (char*)month,
+ DATEBUFSIZE)
+ > DATEBUFSIZE)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
+ }
else if (*ptimestamp_format == 'y' || *ptimestamp_format == 'Y')
- strcat((char*)formatted_date, (char*)year);
+ {
+ if (strlcat((char*)formatted_date, (char*)year,
+ DATEBUFSIZE)
+ > DATEBUFSIZE)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
+ }
else
*(formatted_date + strlen((char*)formatted_date))
= *ptimestamp_format;
@@ -2011,7 +2123,9 @@ process_macro_def(FILE* output, const u8* token,
pmacros = macros + macros_count - 1;
}
CALLOC(pmacros->key, u8, KEYSIZE);
- strcpy((char*)pmacros->key, (char*)token + 2);
+ if (strlcpy((char*)pmacros->key, (char*)token + 2, KEYSIZE)
+ > KEYSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__);
pmacros->value = NULL;
pmacros->value_size = 0;
}
@@ -2488,8 +2602,10 @@ process_inline_footnote(const u8* token, const int read_yaml_macros_and_links,
CALLOC(inline_footnotes[inline_footnote_count - 1], u8,
token_len + 1);
- strcpy((char*)inline_footnotes[inline_footnote_count - 1],
- (char*)token);
+ 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;
}
else
@@ -2529,7 +2645,9 @@ process_footnote(FILE* output, const u8* token, const int footnote_definition,
pfootnotes = footnotes + footnote_count - 1;
}
CALLOC(pfootnotes->key, u8, KEYSIZE);
- strcpy((char*)pfootnotes->key, (char*)token);
+ if (strlcpy((char*)pfootnotes->key, (char*)token, KEYSIZE)
+ > KEYSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__);
pfootnotes->value = NULL;
pfootnotes->value_size = 0;
}
@@ -2718,8 +2836,10 @@ begin_article(FILE* output, const char* source_filename, const u8* link_prefix,
u8* permalink_macro = get_value(macros, macros_count,
(u8*)"permalink", NULL);
- if (ext_in_permalink)
- strcat(link, timestamp_output_ext);
+ if (ext_in_permalink
+ && strlcat(link, timestamp_output_ext, sizeof link)
+ > sizeof link)
+ warning(1, (u8*)"strlcat:%d: Overflow", __LINE__);
if (permalink_url)
process_timestamp(output, link_prefix, permalink_url,
@@ -2868,10 +2988,18 @@ simple_parse_yaml_line(const u8* line, KeyValue** vars, size_t* vars_count,
*pvars = *vars + *vars_count - 1;
}
CALLOC((*pvars)->key, u8, KEYSIZE);
- strcpy((char*)(*pvars)->key, (char*)var_key);
+ if (strlcpy((char*)(*pvars)->key, (char*)var_key,
+ KEYSIZE)
+ > KEYSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
(*pvars)->value_size = strlen((char*)token) + 1;
CALLOC((*pvars)->value, u8, (*pvars)->value_size);
- strcpy((char*)(*pvars)->value, (char*)token);
+ if (strlcpy((char*)(*pvars)->value, (char*)token,
+ (*pvars)->value_size)
+ > (*pvars)->value_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
}
}
free(var_key);
@@ -3120,7 +3248,10 @@ do_line:
pvars = vars + vars_count - 1;
}
CALLOC(pvars->key, u8, KEYSIZE);
- strcpy((char*)pvars->key, (char*)token);
+ if (strlcpy((char*)pvars->key, (char*)token, KEYSIZE)
+ > KEYSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
pvars->value = NULL;
pvars->value_size = 0;
@@ -3172,7 +3303,11 @@ do_line:
if (token_len + entity_len < BUFSIZE)
{
- strcat((char*)token, (char*)entity);
+ if (strlcat((char*)token, (char*)entity,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += entity_len;
}
}
@@ -3213,7 +3348,11 @@ do_line:
if (token_len + entity_len < BUFSIZE)
{
- strcat((char*)token, (char*)entity);
+ if (strlcat((char*)token, (char*)entity,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += entity_len;
}
}
@@ -3255,7 +3394,11 @@ do_line:
if (token_len + tag_len < BUFSIZE)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
}
@@ -3337,7 +3480,11 @@ do_line:
if (token_len + tag_len < BUFSIZE)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
}
@@ -3444,7 +3591,11 @@ do_line:
if (token_len + tag_len < BUFSIZE)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
}
@@ -3487,7 +3638,11 @@ do_line:
if (token_len + tag_len < BUFSIZE)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
}
@@ -3641,7 +3796,11 @@ do_line:
if (token_len + tag_len < BUFSIZE)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
}
@@ -3685,7 +3844,11 @@ do_line:
if (token_len + tag_len < BUFSIZE)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
}
@@ -3760,7 +3923,11 @@ do_line:
{
size_t br_len = strlen("<br>");
*ptoken = 0;
- strcat((char*)ptoken, "<br>");
+ if (strlcat((char*)ptoken, "<br>",
+ token_size - (ptoken - token))
+ > token_size - (ptoken - token))
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += br_len;
output_firstcol = 0;
pline++;
@@ -3769,7 +3936,10 @@ do_line:
else if (IN(state, ST_LINK_MACRO))
{
*ptoken = 0;
- strcpy((char*)link_macro, (char*)token);
+ if (strlcpy((char*)link_macro, (char*)token, BUFSIZE)
+ > BUFSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
*(link_macro + strlen((char*)token)) = 0;
RESET_TOKEN(token, ptoken, token_size);
state &= ~ST_LINK_MACRO;
@@ -3817,16 +3987,24 @@ do_line:
REALLOC(pmacros->value, u8,
pmacros->value_size);
}
- strcat((char*)pmacros->value,
- (char*)token);
+ if (strlcat((char*)pmacros->value,
+ (char*)token,
+ pmacros->value_size)
+ > pmacros->value_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
}
else
{
pmacros->value_size = token_len + 1;
CALLOC(pmacros->value, u8,
pmacros->value_size);
- strcpy((char*)pmacros->value,
- (char*)token);
+ if (strlcpy((char*)pmacros->value,
+ (char*)token,
+ pmacros->value_size)
+ > pmacros->value_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
}
}
}
@@ -3923,12 +4101,12 @@ do_line:
REALLOC(pmacros->value, u8,
pmacros->value_size);
}
- strcat((char*)pmacros->value, "{");
- if (end_tag)
- strcat((char*)pmacros->value, "/");
- strcat(strcat((char*)pmacros->value,
- (char*)token),
- "}");
+ if (snprintf((char*)pmacros->value,
+ pmacros->value_size, "{%s%s}",
+ end_tag ? "/" : "", (char*)token)
+ > pmacros->value_size)
+ warning(1, (u8*)"snprintf:%d: Overflow",
+ __LINE__);
}
*token = 0;
@@ -4011,9 +4189,13 @@ do_line:
*ptoken = 0;
token_len = strlen((char*)token);
- if (token_len + tag_len < BUFSIZE)
+ if (token_len + tag_len + 1 < token_size)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag,
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
}
@@ -4213,7 +4395,10 @@ do_line:
{
size_t lt_len = strlen("<");
*ptoken = 0;
- strcat((char*)token, "<");
+ if (strlcat((char*)token, "<", token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += lt_len;
pline++;
colno++;
@@ -4402,7 +4587,10 @@ do_line:
if (token_len + tag_len < BUFSIZE)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag, token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
@@ -4429,9 +4617,12 @@ do_line:
*ptoken = 0;
token_len = strlen((char*)token);
- if (token_len + tag_len < BUFSIZE)
+ if (token_len + tag_len + 1 < token_size)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag, token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
@@ -4465,9 +4656,12 @@ do_line:
*ptoken = 0;
token_len = strlen((char*)token);
- if (token_len + tag_len + 1 < BUFSIZE)
+ if (token_len + tag_len + 1 < token_size)
{
- strcat((char*)token, (char*)tag);
+ if (strlcat((char*)token, (char*)tag, token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += tag_len;
}
state &= ~ST_LINK_SPAN;
@@ -4618,7 +4812,11 @@ do_line:
plinks = links + links_count - 1;
}
CALLOC(plinks->key, u8, KEYSIZE);
- strcpy((char*)plinks->key, (char*)token);
+ if (strlcpy((char*)plinks->key, (char*)token,
+ KEYSIZE)
+ > KEYSIZE)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
plinks->value = NULL;
plinks->value_size = 0;
pline += 2;
@@ -4647,7 +4845,11 @@ do_line:
link_size = token_len + 1;
CALLOC(link_text, u8, link_size);
}
- strcpy((char*)link_text, (char*)token);
+ if (strlcpy((char*)link_text, (char*)token,
+ link_size)
+ > link_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
*(link_text + token_len) = 0;
pline += 2;
colno += 2;
@@ -4883,7 +5085,10 @@ do_line:
{
size_t quot_len = strlen(""");
*ptoken = 0;
- strcat((char*)token, """);
+ if (strlcat((char*)token, """, token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += quot_len;
pline++;
}
@@ -4899,7 +5104,10 @@ do_line:
{
size_t quot_len = strlen("&");
*ptoken = 0;
- strcat((char*)token, "&");
+ if (strlcat((char*)token, "&", token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
ptoken += quot_len;
pline++;
}
@@ -4929,7 +5137,9 @@ done_line:
}
pvars->value_size = strlen((char*)token) + 1;
CALLOC(pvars->value, u8, pvars->value_size);
- strcpy((char*)pvars->value, (char*)token);
+ if (strlcpy((char*)pvars->value, (char*)token, pvars->value_size)
+ > pvars->value_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow", __LINE__);
}
else if (keep_token)
{
@@ -4940,8 +5150,11 @@ done_line:
REALLOC(token, u8, token_size);
ptoken = token + old_size - 1;
}
- strcat((char*)token,
- ANY(state, ST_IMAGE | ST_LINK) ? " " : "\n");
+ if (strlcat((char*)token,
+ ANY(state, ST_IMAGE | ST_LINK) ? " " : "\n",
+ token_size)
+ > token_size)
+ warning(1, (u8*)"strlcat:%d: Overflow", __LINE__);
ptoken++;
*ptoken = 0;
}
@@ -4974,18 +5187,34 @@ done_line:
REALLOC(pmacros->value, u8,
pmacros->value_size);
}
- strcat((char*)pmacros->value,
- (char*)token);
- strcat((char*)pmacros->value, "\n");
+ 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__);
}
else
{
pmacros->value_size = BUFSIZE;
CALLOC(pmacros->value, u8,
pmacros->value_size);
- strcpy((char*)pmacros->value,
- (char*)token);
- strcat((char*)pmacros->value, "\n");
+ 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__);
}
skip_macro_read:;
}
@@ -5014,18 +5243,34 @@ done_line:
REALLOC(pfootnotes->value, u8,
pfootnotes->value_size);
}
- strcat((char*)pfootnotes->value,
- (char*)token);
- strcat((char*)pfootnotes->value, "\n");
+ 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__);
}
else
{
pfootnotes->value_size = BUFSIZE;
CALLOC(pfootnotes->value, u8,
pfootnotes->value_size);
- strcpy((char*)pfootnotes->value,
- (char*)token);
- strcat((char*)pfootnotes->value, "\n");
+ 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__);
}
*token = 0;
ptoken = token;
@@ -5048,8 +5293,12 @@ done_line:
= strlen((char*)token) + 1;
CALLOC(plinks->value, u8,
plinks->value_size);
- strcpy((char*)plinks->value,
- (char*)token);
+ if (strlcpy((char*)plinks->value,
+ (char*)token,
+ plinks->value_size)
+ > plinks->value_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
}
}
else if (IN(state, ST_HEADING))
@@ -5139,16 +5388,24 @@ done_line:
REALLOC(pfootnotes->value, u8,
pfootnotes->value_size);
}
- strcat((char*)pfootnotes->value,
- (char*)token);
+ if (strlcat((char*)pfootnotes->value,
+ (char*)token,
+ pfootnotes->value_size)
+ > pfootnotes->value_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
}
else
{
pfootnotes->value_size = token_len + 1;
CALLOC(pfootnotes->value, u8,
pfootnotes->value_size);
- strcpy((char*)pfootnotes->value,
- (char*)token);
+ if (strlcpy((char*)pfootnotes->value,
+ (char*)token,
+ pfootnotes->value_size)
+ > pfootnotes->value_size)
+ warning(1, (u8*)"strlcpy:%d: Overflow",
+ __LINE__);
}
*token = 0;
ptoken = token;
@@ -5391,7 +5648,10 @@ main(const int argc, const char** argv)
buffer_size += BUFSIZE;
REALLOC(buffer, u8, buffer_size);
}
- strcat((char*)buffer, (char*)bufline);
+ if (strlcat((char*)buffer, (char*)bufline, buffer_size)
+ > buffer_size)
+ warning(1, (u8*)"strlcat:%d: Overflow",
+ __LINE__);
buffer_len += bufline_len;
}
free(bufline);
diff --git a/strlcat.c b/strlcat.c
@@ -0,0 +1,54 @@
+/* $OpenBSD: strlcat.c,v 1.9 2019/01/25 00:19:26 millert Exp $ */
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left). At most dsize-1 characters
+ * will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+strlcat(char *dst, const char *src, size_t dsize)
+{
+ const char *odst = dst;
+ const char *osrc = src;
+ size_t n = dsize;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end. */
+ while (n-- != 0 && *dst != '\0')
+ dst++;
+ dlen = dst - odst;
+ n = dsize - dlen;
+
+ if (n-- == 0)
+ return(dlen + strlen(src));
+ while (*src != '\0') {
+ if (n != 0) {
+ *dst++ = *src;
+ n--;
+ }
+ src++;
+ }
+ *dst = '\0';
+
+ return(dlen + (src - osrc)); /* count does not include NUL */
+}
diff --git a/strlcpy.c b/strlcpy.c
@@ -0,0 +1,49 @@
+/* $OpenBSD: strlcpy.c,v 1.9 2019/01/25 00:19:26 millert Exp $ */
+
+/*
+ * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+/*
+ * Copy string src to buffer dst of size dsize. At most dsize-1
+ * chars will be copied. Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+strlcpy(char *dst, const char *src, size_t dsize)
+{
+ const char *osrc = src;
+ size_t nleft = dsize;
+
+ /* Copy as many bytes as will fit. */
+ if (nleft != 0) {
+ while (--nleft != 0) {
+ if ((*dst++ = *src++) == '\0')
+ break;
+ }
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src. */
+ if (nleft == 0) {
+ if (dsize != 0)
+ *dst = '\0'; /* NUL-terminate dst */
+ while (*src++)
+ ;
+ }
+
+ return(src - osrc - 1); /* count does not include NUL */
+}
diff --git a/utf8.c b/utf8.c
@@ -1,5 +1,5 @@
/* This program is licensed under the terms of GNU GPL v3 or (at your option)
- * any later version. Copyright (C) 2020-2023 Страхиња Радић.
+ * any later version. Copyright (C) 2020-2024 Страхиња Радић.
* See the file LICENSE for exact copyright and license details. */
#include "utf8.h"
diff --git a/utf8.h b/utf8.h
@@ -1,5 +1,5 @@
/* This program is licensed under the terms of GNU GPL v3 or (at your option)
- * any later version. Copyright (C) 2020-2023 Страхиња Радић.
+ * any later version. Copyright (C) 2020-2024 Страхиња Радић.
* See the file LICENSE for exact copyright and license details. */
#include <stdint.h>
diff --git a/version.h.in b/version.h.in
@@ -1,5 +1,5 @@
/* This program is licensed under the terms of GNU GPL v3 or (at your option)
- * any later version. Copyright (C) 2020-2023 Страхиња Радић.
+ * any later version. Copyright (C) 2020-2024 Страхиња Радић.
* See the file LICENSE for exact copyright and license details. */
#define PROGRAMNAME "slweb"