Skip to content
Closed
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
32 changes: 31 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,37 @@ if(PLATFORM_LINUX OR PLATFORM_FREEBSD)
target_compile_options(rtp2httpd PRIVATE -fstack-protector-strong)
# _FORTIFY_SOURCE requires optimization >= -O1
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(rtp2httpd PRIVATE _FORTIFY_SOURCE=2)
# Toolchains often already define this macro:
# OpenWrt CFLAGS: -D_FORTIFY_SOURCE=1
# Debian/Ubuntu gcc spec: -D_FORTIFY_SOURCE=3 (when optimizing)
# Forcing -D_FORTIFY_SOURCE=2 on top of that produces
# <command-line>: warning: "_FORTIFY_SOURCE" redefined
# and can silently weaken a higher distro default. Only add level 2
# when the compiler/flags do not already provide one.
include(CheckCSourceCompiles)
set(_rtp2httpd_saved_required_flags "${CMAKE_REQUIRED_FLAGS}")
set(_rtp2httpd_saved_required_quiet "${CMAKE_REQUIRED_QUIET}")
set(CMAKE_REQUIRED_QUIET TRUE)
# -O2 lets gcc spec files inject their default _FORTIFY_SOURCE.
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -O2")
check_c_source_compiles(
"#ifndef _FORTIFY_SOURCE\n#error \"_FORTIFY_SOURCE not predefined\"\n#endif\nint main(void) { return 0; }\n"
RTP2HTTPD_HAS_PREDEFINED_FORTIFY_SOURCE)
set(CMAKE_REQUIRED_FLAGS "${_rtp2httpd_saved_required_flags}")
set(CMAKE_REQUIRED_QUIET "${_rtp2httpd_saved_required_quiet}")
unset(_rtp2httpd_saved_required_flags)
unset(_rtp2httpd_saved_required_quiet)
if(NOT RTP2HTTPD_HAS_PREDEFINED_FORTIFY_SOURCE)
target_compile_definitions(rtp2httpd PRIVATE _FORTIFY_SOURCE=2)
set(RTP2HTTPD_FORTIFY_SOURCE "2 (project)")
else()
set(RTP2HTTPD_FORTIFY_SOURCE "toolchain default")
endif()
else()
set(RTP2HTTPD_FORTIFY_SOURCE "disabled (Debug)")
endif()
else()
set(RTP2HTTPD_FORTIFY_SOURCE "not applied")
endif()

# ── Libraries ───────────────────────────────────────────────────────
Expand Down Expand Up @@ -177,5 +206,6 @@ message(STATUS " Platform: ${CMAKE_SYSTEM_NAME}")
message(STATUS " Compiler: ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION}")
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS " Aggressive opt: ${ENABLE_AGGRESSIVE_OPT}")
message(STATUS " Fortify: ${RTP2HTTPD_FORTIFY_SOURCE}")
message(STATUS " Install prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "")
8 changes: 4 additions & 4 deletions src/rtsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2965,7 +2965,7 @@ static void rtsp_parse_play_metadata(rtsp_session_t *session, const struct phr_h
scale = strtod(scale_buf, &end);
while (end && (*end == ' ' || *end == '\t'))
end++;
if (end != scale_buf && end && *end == '\0' && errno != ERANGE && isfinite(scale)) {
if (end != scale_buf && end && *end == '\0' && errno != ERANGE && double_is_finite(scale)) {
metadata->playback_scale = scale;
metadata->playback_scale_known = 1;
}
Expand Down Expand Up @@ -3072,7 +3072,7 @@ static int rtsp_parse_npt_time(const char *value, const char **end_out, double *

errno = 0;
first_component = strtod(value, &component_end);
if (component_end == value || errno == ERANGE || !isfinite(first_component) || first_component < 0.0)
if (component_end == value || errno == ERANGE || !double_is_finite(first_component) || first_component < 0.0)
return -1;

if (*component_end != ':') {
Expand All @@ -3099,11 +3099,11 @@ static int rtsp_parse_npt_time(const char *value, const char **end_out, double *

errno = 0;
seconds = strtod(seconds_start, &seconds_end);
if (seconds_end == seconds_start || errno == ERANGE || !isfinite(seconds) || seconds < 0.0 || seconds >= 60.0)
if (seconds_end == seconds_start || errno == ERANGE || !double_is_finite(seconds) || seconds < 0.0 || seconds >= 60.0)
return -1;

double total = first_component * 3600.0 + (double)minutes * 60.0 + seconds;
if (!isfinite(total))
if (!double_is_finite(total))
return -1;

*end_out = seconds_end;
Expand Down
5 changes: 2 additions & 3 deletions src/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "status.h"
#include "utils.h"
#include <arpa/inet.h>
#include <math.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdbool.h>
Expand Down Expand Up @@ -260,7 +259,7 @@ void stream_send_http_headers(connection_t *conn, const char *content_type, cons
metadata->upstream_payload) < 0;

/* A value we cannot render exactly is dropped rather than approximated. */
if (metadata->playback_scale_known && isfinite(metadata->playback_scale)) {
if (metadata->playback_scale_known && double_is_finite(metadata->playback_scale)) {
if (stream_metadata_format_number(metadata->playback_scale, number, sizeof(number)) == 0)
failed |= stream_metadata_append_header(headers, sizeof(headers), &length,
stream_metadata_header_names[STREAM_HDR_PLAYBACK_SCALE], number) < 0;
Expand All @@ -272,7 +271,7 @@ void stream_send_http_headers(connection_t *conn, const char *content_type, cons
stream_metadata_header_names[STREAM_HDR_PLAYBACK_RANGE],
metadata->playback_range) < 0;
}
if (metadata->media_duration_known && isfinite(metadata->media_duration)) {
if (metadata->media_duration_known && double_is_finite(metadata->media_duration)) {
if (stream_metadata_format_number(metadata->media_duration, number, sizeof(number)) == 0)
failed |= stream_metadata_append_header(headers, sizeof(headers), &length,
stream_metadata_header_names[STREAM_HDR_MEDIA_DURATION], number) < 0;
Expand Down
16 changes: 16 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ int64_t get_realtime_ms(void);
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))

/**
* Return 1 if `value` is a finite IEEE-754 double (not NaN or Inf).
*
* Inspects exponent bits instead of calling isfinite(). With -ffast-math /
* -ffinite-math-only, isfinite() is treated as always-true and Clang emits
* -Wnan-infinity-disabled.
*/
static inline int double_is_finite(double value) {
union {
double d;
uint64_t u;
} conv;
conv.d = value;
return ((conv.u >> 52) & 0x7ffULL) != 0x7ffULL;
}

/**
* Set socket receive buffer size, trying SO_RCVBUFFORCE first.
* SO_RCVBUFFORCE can exceed system limits but requires CAP_NET_ADMIN.
Expand Down
Loading