Search code examples
cdebuggingbuffer-overflow

Why using round() instead of floor() may cause bug/(program error) in C?


I was debugging some code where I need to debug and fix bugs or possible errors. In one of the examples it was said round() may cause bug and fixed it with floor(). However, I didn't quite understand why.

Can anyone give prior example for that?

for (unsigned y = 0; y < round(factor * img->size_y); y++) { // round changed to floor
  for (unsigned x = 0; x < round(factor * img->size_x); x++) { // round changed to floor

    /* Calculate the location of the pixel in the old image */
    unsigned nearest_x = x / factor;
    unsigned nearest_y = y / factor;

    /* Store the pixel */
    image_data_new[y][x] = image_data[nearest_y][nearest_x];
  }
}

In above code round() replaced with floor() to avoid possible attack or bugs.

init code:

struct pixel(*image_data_new)[new_width] =
        (struct pixel(*)[new_width])new_img->px;

where new_width:

unsigned new_width = (unsigned)(img->size_x * factor);
double factor = atof(argv[3]);

Solution

  • your dimension seem to be

    unsigned new_width = (unsigned)(img->size_x * factor);
    

    casting to integer has the same effect as floor in that case.

    Now you're using

    for (unsigned x = 0; x < round(factor * img->size_x); x++) 
    

    that's really looking for trouble, as round is going to yield a value that can be more than new_width if the result to round decimal part is above .5 (and can overflow the buffer). Just use the previously computed value:

    for (unsigned x = 0; x < new_width; x++)