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

This commit is contained in:
Thomas Schmitt 2011-08-17 16:09:05 +00:00
parent fe5efd7b37
commit 7e6dadeb02
4 changed files with 34 additions and 20 deletions

View File

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

View File

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

View File

@ -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 An eventual start address from burn_write_opts_set_start_byte() will be
subtracted from the obtained capacity estimation. Negative results get subtracted from the obtained capacity estimation. Negative results get
defaulted to 0. 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 d The drive to query.
@param o If not NULL: write parameters to be set on drive before query @param o If not NULL: write parameters to be set on drive before query
@return number of most probably available free bytes @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 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 recorded. If tracks are recognizable then it is better to only read
LBAs which are part of some track. 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 d The drive from which to read
@param capacity Will return the result if valid @param capacity Will return the result if valid
@param flag Bitfield for control purposes: Unused yet, submit 0. @param flag Bitfield for control purposes: Unused yet, submit 0.

View File

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