Compare commits

...

4 Commits

Author SHA1 Message Date
Xavier Roche
447c2d1d6f build: gate htssafe pointer-dest regressions with -Werror=attribute-warning
The strcpybuff/strcatbuff/strncatbuff family in htssafe.h silently degrades
to an unchecked strcpy/strcat/strncat when the destination is a bare char*
(capacity unknown); the pointer-destination stubs carry a 'warning' function
attribute to flag every such call. The migration that converted those 241
sites is complete, so any new char* destination is a regression.

Promote that attribute to a hard error in our own build via
-Werror=attribute-warning (gcc) / -Werror=user-defined-warnings (clang),
probed with AX_CHECK_COMPILE_FLAG so each compiler picks up only the spelling
it accepts. htssafe.h is unchanged, so downstream consumers of the installed
header still see a plain warning rather than a build break.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-16 22:29:25 +02:00
Xavier Roche
c86ca62366 Merge pull request #375 from xroche/cleanup/lang-list-size
htsserver: bound LANG_LIST's lang_str copy by its own size
2026-06-16 22:21:50 +02:00
Xavier Roche
9bf741f4b0 htsserver: bound LANG_LIST's lang_str copy by its own size
LANG_LIST bounded its fixed "LANGUAGE_NAME" copy into lang_str[1024] by
buffer_size — the capacity of the *output* buffer, not lang_str's. Harmless
today (the source is a 13-byte literal), but it's the wrong size for that
destination and would become a real overflow if the source ever grew. Bound by
sizeof(lang_str) like the sibling htslang_load call just below it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Xavier Roche <roche@httrack.com>
2026-06-16 22:18:55 +02:00
Xavier Roche
d9c7ea41e8 Merge pull request #374 from xroche/cleanup/htsserver-bounds
Bound the last pointer-destination string copies in htsserver.c
2026-06-16 22:17:50 +02:00
3 changed files with 91 additions and 1 deletions

85
configure vendored
View File

@@ -15541,6 +15541,91 @@ else case e in #(
esac
fi
# Make htssafe.h's pointer-dest 'warning' attribute a hard error in our build
# (migration is at zero; a new char* dest is a regression). gcc/clang each take
# only their own spelling; downstream keeps the plain warning, not a build break.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Werror=attribute-warning" >&5
printf %s "checking whether C compiler accepts -Werror=attribute-warning... " >&6; }
if test ${ax_cv_check_cflags___Werror_attribute_warning+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
ax_check_save_flags=$CFLAGS
CFLAGS="$CFLAGS -Werror=attribute-warning"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ax_cv_check_cflags___Werror_attribute_warning=yes
else case e in #(
e) ax_cv_check_cflags___Werror_attribute_warning=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS=$ax_check_save_flags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Werror_attribute_warning" >&5
printf "%s\n" "$ax_cv_check_cflags___Werror_attribute_warning" >&6; }
if test "x$ax_cv_check_cflags___Werror_attribute_warning" = xyes
then :
DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Werror=attribute-warning"
else case e in #(
e) : ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Werror=user-defined-warnings" >&5
printf %s "checking whether C compiler accepts -Werror=user-defined-warnings... " >&6; }
if test ${ax_cv_check_cflags___Werror_user_defined_warnings+y}
then :
printf %s "(cached) " >&6
else case e in #(
e)
ax_check_save_flags=$CFLAGS
CFLAGS="$CFLAGS -Werror=user-defined-warnings"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ax_cv_check_cflags___Werror_user_defined_warnings=yes
else case e in #(
e) ax_cv_check_cflags___Werror_user_defined_warnings=no ;;
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
CFLAGS=$ax_check_save_flags ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Werror_user_defined_warnings" >&5
printf "%s\n" "$ax_cv_check_cflags___Werror_user_defined_warnings" >&6; }
if test "x$ax_cv_check_cflags___Werror_user_defined_warnings" = xyes
then :
DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Werror=user-defined-warnings"
else case e in #(
e) : ;;
esac
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fstrict-aliasing -Wstrict-aliasing" >&5
printf %s "checking whether C compiler accepts -fstrict-aliasing -Wstrict-aliasing... " >&6; }
if test ${ax_cv_check_cflags___fstrict_aliasing__Wstrict_aliasing+y}

View File

@@ -84,6 +84,11 @@ AX_CHECK_COMPILE_FLAG([-Wformat-nonliteral], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -W
AX_CHECK_COMPILE_FLAG([-Wmissing-parameter-type], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wmissing-parameter-type"])
AX_CHECK_COMPILE_FLAG([-Wold-style-definition], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wold-style-definition"])
AX_CHECK_COMPILE_FLAG([-Wignored-qualifiers], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Wignored-qualifiers"])
# Make htssafe.h's pointer-dest 'warning' attribute a hard error in our build
# (migration is at zero; a new char* dest is a regression). gcc/clang each take
# only their own spelling; downstream keeps the plain warning, not a build break.
AX_CHECK_COMPILE_FLAG([-Werror=attribute-warning], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Werror=attribute-warning"])
AX_CHECK_COMPILE_FLAG([-Werror=user-defined-warnings], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -Werror=user-defined-warnings"])
AX_CHECK_COMPILE_FLAG([-fstrict-aliasing -Wstrict-aliasing], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstrict-aliasing -Wstrict-aliasing"])
AX_CHECK_COMPILE_FLAG([-fstack-protector], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstack-protector"])
AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [DEFAULT_CFLAGS="$DEFAULT_CFLAGS -fstack-clash-protection"])

View File

@@ -1783,7 +1783,7 @@ static int LANG_LIST(const char *path, char *buffer, size_t buffer_size) {
buffer[0] = '\0';
do {
QLANG_T(i);
strlcpybuff(lang_str, "LANGUAGE_NAME", buffer_size);
strlcpybuff(lang_str, "LANGUAGE_NAME", sizeof(lang_str));
htslang_load(lang_str, sizeof(lang_str), path);
if (strlen(lang_str) > 0) {
if (buffer[0])