Browse Source

Bug fix: stdio sizes > 4 TB - 32 kB caused integer rollover

1.1.6
Thomas Schmitt 10 years ago
parent
commit
7e6dadeb02
  1. 2
      cdrskin/cdrskin_timestamp.h
  2. 43
      libburn/drive.c
  3. 5
      libburn/libburn.h
  4. 4
      libburn/transport.h

2
cdrskin/cdrskin_timestamp.h

@ -1 +1 @@
#define Cdrskin_timestamP "2011.08.08.121355"
#define Cdrskin_timestamP "2011.08.17.160854"

43
libburn/drive.c

@ -374,8 +374,13 @@ int burn_drive_grab(struct burn_drive *d, int le)
if (stat_ret != -1 && S_ISREG(stbuf.st_mode) &&
stbuf.st_size > 0) {
d->status = BURN_DISC_APPENDABLE;
d->role_5_nwa = stbuf.st_size / 2048 +
!!(stbuf.st_size % 2048);
if (stbuf.st_size / (off_t) 2048
>= 0x7ffffff0) {
d->status = BURN_DISC_FULL;
d->role_5_nwa = 0x7ffffff0;
} else
d->role_5_nwa = stbuf.st_size / 2048 +
!!(stbuf.st_size % 2048);
} else
d->status = BURN_DISC_BLANK;
} else {
@ -1464,13 +1469,14 @@ static int burn_drive__is_rdwr(char *fname, int *stat_ret,
st_ret = stat(fname, &stbuf);
if (st_ret != -1) {
is_rdwr = burn_os_is_2k_seekrw(fname, 0);
if (S_ISREG(stbuf.st_mode))
if (S_ISREG(stbuf.st_mode)) {
read_size = stbuf.st_size;
else if (is_rdwr) {
ret = 1;
} else if (is_rdwr)
ret = burn_os_stdio_capacity(fname, &read_size);
if (ret <= 0)
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
}
if (ret <= 0 ||
read_size / (off_t) 2048 >= (off_t) 0x7ffffff0)
read_size = (off_t) 0x7ffffff0 * (off_t) 2048;
}
if (is_rdwr && fd >= 0) {
@ -1614,8 +1620,13 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname)
(burn_drive_role_4_allowed & 8)) {
d->status = BURN_DISC_APPENDABLE;
d->block_types[BURN_WRITE_SAO] = 0;
d->role_5_nwa = stbuf.st_size / 2048 +
!!(stbuf.st_size % 2048);
if (stbuf.st_size / (off_t) 2048
>= 0x7ffffff0) {
d->status = BURN_DISC_FULL;
d->role_5_nwa = 0x7ffffff0;
} else
d->role_5_nwa = stbuf.st_size / 2048 +
!!(stbuf.st_size % 2048);
} else {
d->status = BURN_DISC_BLANK;
d->block_types[BURN_WRITE_SAO] =
@ -2713,11 +2724,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
size = d->media_capacity_remaining;
burn_os_stdio_capacity(d->devname, &size);
burn_drive_set_media_capacity_remaining(d, size);
/* >>> This looks wrong ! */
/* >>> should add file size */
o->start_range_high = size;
o->start_range_high = d->media_capacity_remaining;
o->start_alignment = 2048; /* imposting a drive, not a file */
o->might_do_sao = 4;
o->might_do_tao = 2;
@ -2732,10 +2739,7 @@ int burn_disc_get_multi_caps(struct burn_drive *d, enum burn_write_types wt,
/* >>> start_range_low = file size rounded to 2048 */;
/* >>> This looks wrong ! */
/* >>> should add file size */
o->start_range_high = size;
o->start_range_high = d->media_capacity_remaining;
o->start_alignment = 2048; /* imposting a drive, not a file */
if (s == BURN_DISC_APPENDABLE) {
if (wt == BURN_WRITE_SAO || wt == BURN_WRITE_RAW)
@ -3148,10 +3152,13 @@ int burn_drive_find_by_thread_pid(struct burn_drive **d, pid_t pid,
*/
int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value)
{
if (value / (off_t) 2048 > (off_t) 0x7ffffff0)
value = ((off_t) 0x7ffffff0) * (off_t) 2048;
d->media_capacity_remaining = value;
return 1;
}
/* ts A81215 : API */
int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag)
{

5
libburn/libburn.h

@ -1393,6 +1393,9 @@ int burn_disc_get_msc1(struct burn_drive *d, int *start_lba);
An eventual start address from burn_write_opts_set_start_byte() will be
subtracted from the obtained capacity estimation. Negative results get
defaulted to 0.
If the drive is actually a file in a large filesystem or a large block
device, then the capacity is curbed to a maximum of 0x7ffffff0 blocks
= 4 TB - 32 KB.
@param d The drive to query.
@param o If not NULL: write parameters to be set on drive before query
@return number of most probably available free bytes
@ -3067,6 +3070,8 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address,
can be read via burn_read_data() although some of them may never have been
recorded. If tracks are recognizable then it is better to only read
LBAs which are part of some track.
If the drive is actually a large file or block device, then the capacity
is curbed to a maximum of 0x7ffffff0 blocks = 4 TB - 32 KB.
@param d The drive from which to read
@param capacity Will return the result if valid
@param flag Bitfield for control purposes: Unused yet, submit 0.

4
libburn/transport.h

@ -293,7 +293,9 @@ struct burn_drive
int media_lba_limit;
/* ts A81210 : Upper limit of readable data size,
0x7fffffff = unknown */
0x7fffffff = unknown
0x7ffffff0 = 32 bit overflow, or unknown stdio size
*/
int media_read_capacity;
/* ts B10314 : Next Writeable Adress for drive_role == 5 */

Loading…
Cancel
Save