libcdio-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libcdio-devel] udf_read_sectors cannot handle offsets past 2 GB


From: Pete Batard
Subject: [Libcdio-devel] udf_read_sectors cannot handle offsets past 2 GB
Date: Mon, 23 Jan 2012 20:50:11 +0000
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0) Gecko/20111222 Thunderbird/9.0.1

With the previous fix applied, the next issue we are facing is in udf_read_sectors() and more specifically the fact that it uses 32 bit values when ran on 32 bit systems, for i_byte_offset.

The i_byte_offset value is used with SEEK_SET, so it should always be positive, however if you modify the code to have something like:

  i_byte_offset = (i_start * UDF_BLOCKSIZE);
  if (i_byte_offset < 0) {
    cdio_warn("i_byte_offset = %d (i_start = %d)",
      i_byte_offset, i_start);
    return DRIVER_OP_ERROR;
  }

You end up with:

Extracting: /mnt/data/test//sources/install.wim
++ WARN: i_byte_offset = -2147483648 (i_start = 1048576)
  Error reading UDF file /sources/install.wim
--DEBUG: closed source...


Now, the problem we are facing when trying to address this bug is we are feeding i_byte_offset to cdio_stream_seek() which in turn calls the seek() function from cdio_stream of type:

  typedef driver_return_code_t(*cdio_data_seek_t)
               (void *user_data, long offset, int whence);

Unfortunately, this definition, as well as its actual implementation in _cdio_stdio.c follows POSIX's fseek() and uses a long for the offset. This means checkmate on 32 bit platforms as long as fseek is used.

In other words, the current libcdio stream implementation is limited to 2 GB streams on 32 bit platforms...

My proposal then would be to switch to fseeko [1], which takes an off_t, as well as redefine cdio_data_seek_t to also take an off_t instead of a long. With the ability to set off_t to 64 bit for large file support, this should do the trick. However this is expected to break any libcdio application that implements their own stream using a seek() that follows the fseek prototype. Currently, I have no idea if this is a valid concern or not.

On the other hand, there exists an AC_FUNC_FSEEKO autoconf directive to check fseeko support, so we should at least be able to implement a fallback to fseek if fseeko is not available, with the expectation that this will only occur on 32 bit platforms so no casting issue.

Does the above look like a workable approach to fix this issue? Or do you see another possibility?

Regards,

/Pete

[1] http://fclose.com/p/linux/man/3p-fseeko/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]