Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/htsback.c
Original file line number Diff line number Diff line change
Expand Up @@ -1101,9 +1101,10 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
strcpybuff(back[p].r.msg, "Empty compressed file");
}
} else {
snprintf(back[p].r.msg, sizeof(back[p].r.msg),
"Open error when decompressing (can not create temporary file %s)",
back[p].tmpfile);
htsblk_failf(&back[p].r,
"Open error when decompressing (can not create "
"temporary file %s)",
back[p].tmpfile);
back[p].tmpfile[0] = '\0';
back[p].r.statuscode = STATUSCODE_INVALID;
}
Expand Down Expand Up @@ -1188,11 +1189,11 @@ int back_finalize(httrackp * opt, cache_back * cache, struct_back * sback,
a local write's errno behind, and 0 for a bad stream. */
if (errno != 0)
back_report_write_failure(opt, &back[p]);
snprintf(back[p].r.msg, sizeof(back[p].r.msg),
codec == HTS_CODEC_UNSUPPORTED
? "Unsupported Content-Encoding (%s)"
: "Error when decompressing (%s)",
back[p].r.contentencoding);
htsblk_failf(&back[p].r,
codec == HTS_CODEC_UNSUPPORTED
? "Unsupported Content-Encoding (%s)"
: "Error when decompressing (%s)",
back[p].r.contentencoding);
/* Drop the undecoded body so the writer can't commit the
coded bytes as the page; url_sav is left untouched. */
if (!back[p].r.is_write)
Expand Down
20 changes: 6 additions & 14 deletions src/htslib.c
Original file line number Diff line number Diff line change
Expand Up @@ -2326,8 +2326,7 @@ T_SOC newhttp_addr(httrackp *opt, const char *_iadr, htsblk *retour, int port,
// a port filter named; an empty "host:" just means the default (#614)
if (a[1] != '\0' && !hts_parse_url_port(a + 1, &port)) {
if (retour != NULL) {
snprintf(retour->msg, sizeof(retour->msg), "Invalid port: %s",
a + 1);
htsblk_failf(retour, "Invalid port: %s", a + 1);
}
return INVALID_SOCKET;
}
Expand Down Expand Up @@ -2355,13 +2354,7 @@ T_SOC newhttp_addr(httrackp *opt, const char *_iadr, htsblk *retour, int port,
printf("erreur gethostbyname\n");
#endif
if (retour != NULL) {
#ifdef _WIN32
snprintf(retour->msg, sizeof(retour->msg),
"Unable to get server's address: %s", error);
#else
snprintf(retour->msg, sizeof(retour->msg),
"Unable to get server's address: %s", error);
#endif
htsblk_failf(retour, "Unable to get server's address: %s", error);
}
return INVALID_SOCKET;
}
Expand Down Expand Up @@ -2408,8 +2401,8 @@ T_SOC newhttp_addr(httrackp *opt, const char *_iadr, htsblk *retour, int port,
&bind_addr, &error) == NULL
|| bind(soc, &SOCaddr_sockaddr(bind_addr),
SOCaddr_size(bind_addr)) != 0) {
snprintf(retour->msg, sizeof(retour->msg),
"Unable to bind the specificied server address: %s", error);
htsblk_failf(
retour, "Unable to bind the specificied server address: %s", error);
deletesoc(soc);
return INVALID_SOCKET;
}
Expand All @@ -2430,9 +2423,8 @@ T_SOC newhttp_addr(httrackp *opt, const char *_iadr, htsblk *retour, int port,
#endif
char errbuf[HTS_STRERROR_SIZE];

snprintf(retour->msg, sizeof(retour->msg),
"Non-blocking socket failed: %s",
hts_strerror(last_errno, errbuf, sizeof(errbuf)));
htsblk_failf(retour, "Non-blocking socket failed: %s",
hts_strerror(last_errno, errbuf, sizeof(errbuf)));
deletesoc(soc);
return INVALID_SOCKET;
}
Expand Down
2 changes: 1 addition & 1 deletion src/htslib.h
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ HTS_STATIC int strcmpnocase(const char *a, const char *b) {
#ifdef _WIN32
#define strcasecmp(a,b) stricmp(a,b)
#define strncasecmp(a,b,n) strnicmp(a,b,n)
#define snprintf _snprintf
/* No snprintf alias: _snprintf leaves a truncated string unterminated. */
#endif

/* MSVC ships these POSIX functions under other names. Kept out of the installed
Expand Down
51 changes: 51 additions & 0 deletions tests/491_no-legacy-printf-alias.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/bin/bash
#
# No build may give a C99 printf call another implementation under its own
# name. A Linux build cannot see such an alias, so this scan is the only guard.

set -euo pipefail

# shellcheck source=tests/testlib.sh
. "${0%"${0##*/}"}./testlib.sh"

top="${abs_top_srcdir:?not run under make check}"
test -f "$top/src/htslib.h" || fail "no $top/src/htslib.h"

work=$(mktemp -d "${TMPDIR:-/tmp}/printfalias.XXXXXX") || fail "no tmpdir"
cleanup_push rm -rf "$work"

family='v?(f|s|sn)?printf|v?asprintf'
# A macro whose name IS the C99 call, so every later use silently changes
# meaning. A wrapper named otherwise, such as htssafe.h's sprintfbuff, is fine.
source_re="^[[:space:]]*#[[:space:]]*define[[:space:]]+($family)[[:space:](]"
# The same alias handed to the compiler instead: -Dsnprintf=_snprintf, or a
# Visual Studio PreprocessorDefinitions entry.
build_re="($family)="

sources() { # sources DIR -> the .c and .h files under it
find "$1" \( -name '*.c' -o -name '*.h' \) -print | LC_ALL=C sort
}

sources "$top/src" >"$work/files"
# A find that silently narrowed would report a clean tree, so floor the count.
test "$(lines_of "$work/files")" -ge 100 ||
fail "only $(lines_of "$work/files") sources found under $top/src"
xargs grep -nHE "$source_re" <"$work/files" >"$work/found" || true

ls "$top"/configure.ac "$top"/*/Makefile.am "$top"/src/*.vcxproj >"$work/builds"
xargs grep -nHE "$build_re" <"$work/builds" >>"$work/found" || true

# Control: both scans must fire on the lines this test exists to keep out.
mkdir -p "$work/ctl"
printf '#define snprintf _snprintf\n' >"$work/ctl/legacy.h"
printf '<PreprocessorDefinitions>snprintf=_snprintf</PreprocessorDefinitions>\n' \
>"$work/ctl/legacy.vcxproj"
grep -qE "$source_re" "$work/ctl/legacy.h" ||
fail "the source scan cannot see a legacy alias, so a clean result proves nothing"
grep -qE "$build_re" "$work/ctl/legacy.vcxproj" ||
fail "the build scan cannot see a legacy alias, so a clean result proves nothing"

test ! -s "$work/found" ||
fail_dump "a C99 printf call is aliased to another implementation under its own name. Call the real one, or give the wrapper its own name" "$work/found"

echo "scanned $(lines_of "$work/files") sources and $(lines_of "$work/builds") build files, aliases: 0"
Loading