[nginx] Mp4: fixed ngx_http_mp4_seek_key_frame().

Maxim Dounin mdounin at mdounin.ru
Tue Mar 10 01:39:22 UTC 2026


details:   http://freenginx.org/hg/nginx/rev/a181973aa820
branches:  
changeset: 9475:a181973aa820
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Tue Mar 10 04:31:25 2026 +0300
description:
Mp4: fixed ngx_http_mp4_seek_key_frame().

Previously, ngx_http_mp4_seek_key_frame() might return key frame prefix
larger than start_sample provided in function arguments, notably on an
invalid stss entry with zero sample_number.  This resulted in backwards
loop in ngx_http_mp4_crop_stts_data() to incorrectly access data before
the stts atom entries (and stop at the stts atom header mostly by chance).

The fix is to make sure ngx_http_mp4_seek_key_frame() always returns
a value equal or smaller than start_sample provided, regardless of the
stss entries.  Invalid entries with zero sample_number now will be
interpreted as if there very large sample_number, so the previous one
will be returned.

diffstat:

 src/http/modules/ngx_http_mp4_module.c |  7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diffs (21 lines):

diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -2528,13 +2528,14 @@ ngx_http_mp4_seek_key_frame(ngx_http_mp4
     entry = (uint32_t *) data->pos;
     end = (uint32_t *) data->last;
 
-    /* sync samples starts from 1 */
-    start_sample++;
-
     key_prefix = 0;
 
     while (entry < end) {
         sample = ngx_mp4_get_32value(entry);
+
+        /* sync samples starts from 1 */
+        sample--;
+
         if (sample > start_sample) {
             break;
         }


More information about the nginx-devel mailing list