[libdvdnav-devel] [Git][videolan/libdvdread][master] 4 commits: dvd_input: fix stream seek offset truncation on 32-bit off_t
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Wed Jul 29 13:07:18 UTC 2026
Jean-Baptiste Kempf pushed to branch master at VideoLAN / libdvdread
Commits:
d824fe61 by Kacper Michajłow at 2026-07-29T15:04:24+02:00
dvd_input: fix stream seek offset truncation on 32-bit off_t
The byte offset passed to the pf_seek callback was computed in off_t
arithmetic before being widened to the callback's uint64_t parameter.
On platforms where off_t is 32-bit (Windows) this truncated seeks
beyond 2 GiB. Compute the offset in uint64_t directly.
- - - - -
1c2c33eb by Kacper Michajłow at 2026-07-29T15:04:24+02:00
file_win32: clamp oversized reads, callers must handle partial reads anyway
win32 CRT read() takes uint as input read size and returns int.
- - - - -
fff6d674 by Kacper Michajłow at 2026-07-29T15:04:24+02:00
dvd_input: keep block count as int
No need to use off_t here, and cause type mismatches with seek functions
that takes number of blocks as int anyway.
- - - - -
21cdfe9f by Kacper Michajłow at 2026-07-29T15:04:24+02:00
ifo_read: add explicit cast to suppres warnings
We convert number of bytes to count and we know that this will never be
huge value, safe to store as u16.
- - - - -
3 changed files:
- src/dvd_input.c
- src/file/file_win32.c
- src/ifo_read.c
Changes:
=====================================
src/dvd_input.c
=====================================
@@ -109,7 +109,8 @@ struct dvd_input_s {
/* */
void *priv;
dvd_logger_cb *logcb;
- off_t ipos;
+ /* Current position as a block index, -1 after a failed read */
+ int ipos;
/* This variable keeps track of the current files stream_type,
* and in turn determined the decryption method to use */
@@ -314,7 +315,7 @@ static int file_seek(dvd_input_t dev, int blocks)
if (dev->stream_cb) {
/* Returns 0 on successful completion and -1 on error */
- pos = dev->stream_cb->pf_seek(dev->priv, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN);
+ pos = dev->stream_cb->pf_seek(dev->priv, blocks * (uint64_t)DVD_VIDEO_LB_LEN);
if (!pos) {
dev->ipos = blocks;
@@ -324,7 +325,7 @@ static int file_seek(dvd_input_t dev, int blocks)
pos = dev->fs->file_seek(dev->file, (off64_t)blocks * (off64_t)DVD_VIDEO_LB_LEN, SEEK_SET);
if (pos >= 0) {
- dev->ipos = pos / DVD_VIDEO_LB_LEN;
+ dev->ipos = (int)(pos / DVD_VIDEO_LB_LEN);
}
}
@@ -332,7 +333,7 @@ static int file_seek(dvd_input_t dev, int blocks)
return pos;
}
- return (int) dev->ipos;
+ return dev->ipos;
}
/**
@@ -349,7 +350,8 @@ static int file_title(dvd_input_t dev UNUSED, int block UNUSED)
static int file_read(dvd_input_t dev, void *buffer, int blocks,
int flags UNUSED)
{
- size_t len, bytes, blocks_read;
+ size_t len, bytes;
+ int blocks_read;
len = (size_t)blocks * DVD_VIDEO_LB_LEN;
bytes = 0;
@@ -382,12 +384,12 @@ static int file_read(dvd_input_t dev, void *buffer, int blocks,
if(ret < 0)
return ret;
- return (int) blocks_read;
+ return blocks_read;
}
len -= ret;
bytes += ret;
- blocks_read = bytes / DVD_VIDEO_LB_LEN;
+ blocks_read = (int)(bytes / DVD_VIDEO_LB_LEN);
}
dev->ipos += blocks_read;
=====================================
src/file/file_win32.c
=====================================
@@ -18,6 +18,7 @@
*/
#include <io.h>
+#include <limits.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
@@ -73,7 +74,11 @@ static ssize_t file_read_default(void *file, char *buf, size_t size)
return 0;
}
- return read(*(int*)file, buf, size);
+ /* Clamp oversized reads, callers must handle partial reads anyway. */
+ if (size > INT_MAX)
+ size = INT_MAX;
+
+ return read(*(int*)file, buf, (unsigned int)size);
}
static off64_t file_seek_default(void *file, off64_t offset, int whence)
=====================================
src/ifo_read.c
=====================================
@@ -2395,7 +2395,7 @@ int ifoRead_TT_SRPT(ifo_handle_t *ifofile) {
if(tt_srpt->nr_of_srpts>info_length/sizeof(title_info_t)){
Log1(ifop->ctx, "data mismatch: info_length (%zd)!= nr_of_srpts (%d). Truncating.",
info_length/sizeof(title_info_t),tt_srpt->nr_of_srpts);
- tt_srpt->nr_of_srpts=info_length/sizeof(title_info_t);
+ tt_srpt->nr_of_srpts=(uint16_t)(info_length/sizeof(title_info_t));
}
for(i = 0; i < tt_srpt->nr_of_srpts; i++) {
@@ -2979,7 +2979,7 @@ static int ifoRead_C_ADT_internal(ifo_handle_t *ifofile,
is to high, they high ones are never referenced though. */
if(info_length / sizeof(cell_adr_t) < c_adt->nr_of_vobs) {
Log1(ifop->ctx, "C_ADT nr_of_vobs > available info entries");
- c_adt->nr_of_vobs = info_length / sizeof(cell_adr_t);
+ c_adt->nr_of_vobs = (uint16_t)(info_length / sizeof(cell_adr_t));
}
c_adt->cell_adr_table = calloc(1, info_length);
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/42ace18eaf15e1c929ed06fbfd3b40fb409b8c8c...21cdfe9f23079277e0b4858b6ca37abd8d94ec7e
--
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/42ace18eaf15e1c929ed06fbfd3b40fb409b8c8c...21cdfe9f23079277e0b4858b6ca37abd8d94ec7e
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help
More information about the libdvdnav-devel
mailing list