buffer size rounding for >2G fails

Bug #600893 reported by Stuart R Balfour
6
This bug affects 1 person
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,sz=the_buffer_size;

        while (sz>>=1) shift++;
        if (shift<20) shift=20; /* 1MB is minumum */
        sz = 1<<shift;
        if (sz < the_buffer_size) sz<<=1;
        the_buffer_size = sz;
    }

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(the_buffer_size); // index of high bit
if (1<<t!=the_buffer_size || t<10) // not 2^n or <1M
     the_buffer_size=1 <<( (t<10)?10
                                        :(t==31)?31
                                        :t+1 ); // round up to 2^n

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.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.