buffer size rounding for >2G fails
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
dvd+rw-tools (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
Binary package hint: dvd+rw-tools
dvd+rw-tools-7.1-6
Inspection of the following code in growisofs.c
/*
* Ensure the_buffer_size is degree of 2
*/
{ unsigned int shift=0,
while (sz>>=1) shift++;
if (shift<20) shift=20; /* 1MB is minumum */
sz = 1<<shift;
if (sz < the_buffer_size) sz<<=1;
}
Example: for input the_buffer_size 2G+1 yields the_buffer_size = 0. The while loop
will shift 31 times before sz is 0, so shift is 31, and sz=1<<31 or 2G. But 2G < 2G+1
below, so sz gets shifted up again, the bit falls off, and sz is now zero.
The buffer size needs a maximum of 2G as well as some minimum, i.e. 1M(?). Even
at 1X, we run a high risk of buffer underruns@1M. Maybe we ought to adjust this
as part of the bug fix.
It is apparent that the algorithm intends to round the_buffer_size up if it is not an even
power of two. The algorithm labors. There is a simple and elegant way to round up
to a power of 2 without all the tricky bit shifting. Find it and fix it. Better yet, define
or find something generally useful like log2(n), then use it here. I.e.,
unsigned int t=log2(
if (1<<t!=
the_
Of course, unless there is hardware/asm support (on i386, it's a BSR
instruction), computing log2(n) isn't especially cheap or elegant. But
from a modularity and readability point of view, the code is impeccable
and therefore substantially more likely to be correct.
nearest and employ it here.