Commit a7b20ee103 for ffmpeg

commit a7b20ee103356f2ca5ffcdc6f3c38ae0853e0648
Author: Furkan Efe Can <caglarf646@gmail.com>
Date:   Tue Oct 13 00:39:45 2026 +0300

    avformat/rtsp: Validate the SampleRate SDP attribute

    sdp_parse_line() stored the "SampleRate:integer;" attribute straight into
    codecpar->sample_rate without any check:

        st = s->streams[s->nb_streams - 1];
        st->codecpar->sample_rate = atoi(p);

    The value comes from the SDP description, i.e. from the server, so a
    negative sample rate ends up on the stream. atoi() additionally has
    undefined behaviour when the value does not fit into an int, which is
    why 088f08db71 removed it from matroskaenc.

    Measured with a minimal SDP fed to the sdp demuxer, before this patch:

        SampleRate:integer;48000                  -> sample_rate = 48000
        SampleRate:integer;-1                     -> sample_rate = -1
        SampleRate:integer;99999999999999999999   -> sample_rate = -1

    Every other demuxer rejects such values (4xm.c, adxdec.c, 3dostr.c,
    apac.c, ads.c all test sample_rate <= 0), and rtsp.c itself already
    guards the rtpmap sample rate and channel count with "if (i > 0)" a few
    hundred lines earlier, so only this attribute was left unchecked.

    Use strtol() with base 10, check errno for ERANGE, and ignore values
    outside the valid range, keeping whatever rate the rtpmap line
    established.  Base 10 matters: with base 0 a leading zero would select
    octal and silently reinterpret existing decimal rates.  The ERANGE test
    matters where LONG_MAX == INT_MAX, since there a positive overflow
    returns INT_MAX and would otherwise pass the upper bound check.

    Measured after the patch, with the rtpmap rate held at 44100:

        SampleRate:integer;48000                  -> 48000 Hz
        SampleRate:integer;048000                 -> 48000 Hz
        SampleRate:integer;044100                 -> 44100 Hz
        SampleRate:integer;-1                     -> rejected, keeps 44100
        SampleRate:integer;0                      -> rejected, keeps 44100
        SampleRate:integer;99999999999999999999   -> rejected, keeps 44100

    Note this is defence in depth rather than a fix for a reachable crash:
    nothing in the RTP/RDT path divides by sample_rate, and avcodec.c
    rejects a negative rate when the decoder is opened.

    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    Signed-off-by: Furkan Efe Can <caglarf646@gmail.com>

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index eef1e10eb2..29f219c366 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -681,8 +681,17 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
                 rt->transport = RTSP_TRANSPORT_RDT;
         } else if (av_strstart(p, "SampleRate:integer;", &p) &&
                    s->nb_streams > 0) {
-            st = s->streams[s->nb_streams - 1];
-            st->codecpar->sample_rate = atoi(p);
+            long sample_rate;
+
+            errno = 0;
+            sample_rate = strtol(p, NULL, 10);
+            if (errno == ERANGE || sample_rate <= 0 || sample_rate > INT_MAX) {
+                av_log(s, AV_LOG_WARNING,
+                       "Invalid SampleRate %ld in SDP, ignoring\n", sample_rate);
+            } else {
+                st = s->streams[s->nb_streams - 1];
+                st->codecpar->sample_rate = sample_rate;
+            }
         } else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
             // RFC 4568
             rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];