Integer overflow while malloc memory - c

We have struct image pointer:
struct image {
uint16_t size_x;
uint16_t size_y;
struct pixel *px;
};
and:
img->px = malloc(sizeof(struct pixel) * height * width);
where pixel:
struct pixel {
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t alpha;
}
where width & height:
long height = strtol(height_arg, &end_ptr, 10);
long width = strtol(width_arg, &end_ptr, 10);
So, since we use malloc() to allocate memory and it uses size_t for allocating.
Since we multiplying height and width which are long typed to allocate memory, is there integer overflow expected? If, yes then how to handle it?
Later on we iterate over picture and color it:
for (int i = 0; i < img->size_y; i++) {
for (int j = 0; j < img->size_x; j++) {
image_data[i][j].red = palette[0].red;
image_data[i][j].green = palette[0].green;
image_data[i][j].blue = palette[0].blue;
image_data[i][j].alpha = 0xff;
}
}
where
img->size_x = width;
img->size_y = height;

Integer overflow may happen at every point of this program:
strtol("9999999999", &end_ptr, 10) -> will overflow and return LONG_MAX
height * width -> can overflow and return a negative value (since those are signed longs)
sizeof(struct pixel) * height * width
-> can return a bigger value than UNSIGNED_MAX, wrapping around to a smaller value than expected
Malloc can allocate some very large data segments, and may not fail immediately, so you should seriously consider verifying your results before allocating.

Yes, there is a risk.
You can check it like this:
struct pixel *px;
if (height > SIZE_MAX / width || sizeof *px > SIZE_MAX / (width * height)) {
// Handle overflow
}
px = malloc(sizeof *px * width * height);
if(!px) {
// Handle allocation error
}
img->px = px;

Related

Resizing a the dimensions of a pixel pgm image in C

What i am trying to do i resize the a regular pgm image,by a factor of 3--100X100 becomes 33X33,i am using pointer array to store the original image and the resized image, the original image will be 10000 long and the resized image will be 1089 long, I am trying to do get the every 3rd element in the width dimension and skipping two width rows(as height also needs to be reduced),I keep getting a weird blurry image when I write it in a pgm output,i get there might be a little difference as we are rounding height and width,this is just a bit of the code.
enter code here
int k,l,m;
image =(unsigned char*) malloc((width*height) * sizeof(unsigned char));
int thumbHeight=round(height/3);
int thumbWidth =round(width/3);
resizedImage =(unsigned char*) malloc(((resizedWidth*resizedHeight)) * sizeof(unsigned char));
for(l=0;l<resizedHeight;l++){
for(k=0;k<resizedWidth;k++){
*resizedImage= *image;
image++;
image++;
}
//skipping two lines
for (m=0;m<width*2;m++){
image++;
}
}
maybe:
unsigned char *resize(const unsigned char *source, unsigned char *dest, size_t origx, size_t origy, size_t destx)
{
double ratio = (double)destx / origx;
double stepx = (double)origx / destx;
double stepy = (double)origy / (origy * ratio);
for(size_t y = 0; y < origy * ratio; y++)
{
for(size_t x = 0; x < destx; x++)
{
dest[y * destx + x] = source[(ssize_t)((y * stepy) * origx + x * stepx)];
}
}
return dest;
}
But I did not run this so it may be buggy.

Flipping Vertices with C

I am trying to flip an image in C vertically so if the image is < it will end up > and my function includes
//Setting the struct up for the pixel's
struct pixel
{
unsigned char red;
unsigned char green;
unsigned char blue;
};
//Setting the struct up for the Image Type and scanning in the pxiels into an array
struct ImageType
{
char ppImage[3];
char comment[256];
char newlinechar;
int width, height;
int maxColor = 255;
struct pixel image[100][100];
};
//Function in order to flip the image, going from the left most pixel flipping with the right most
void MirrorVertical(struct ImageType imgur)
{
int x,y;
const int middle = imgur.width / 2;
struct pixel tmp;
struct *pixel p;
for(y=0; y < imgur.height; ++y)
{
p = tmp + y * imgur.width;
for(x=0; x < middle; ++x)
{
tmp = p[x];
p[x] = p[imgur.width - 1 - x];
p[imgur.width - 1 - x] = tmp;
}
}
}
I got my structs to work but for some reason my function will not output it, I am scanning in the image into from a struct so....
//Scanning in the pixels for the first image
for(i=imageA.height-1; i <= 0; i--)
{
for(j=0; j < imageA.width; j++)
{
scanf("%hhu", &imageA.image[i][j].red);
scanf("%hhu", &imageA.image[i][j].green);
scanf("%hhu", &imageA.image[i][j].blue);
}
}
What am I doing wrong in my function?
It should be
for(x=0; x < width; x++)
{
for(y = 0; y < height/2; y++)
{
temp = imgur.image[x][y];
imgur.image[x][y] = imgur.image[x][height-y-1]
imgur.image[x][height-y-1] = temp;
}
}
}
Shouldn't this: for(i=imageA.height-1; i <= 0; i--) be for(i=imageA.height-1; i >= 0; i--)? (in the "scanning in the pixels for the first image" code)
I imagine your compiler must be complaining about
struct pixel tmp;
struct *pixel p;
for(y=0; y < imgur.height; ++y)
{
p = tmp + y * imgur.width;
You are adding a struct to an int and allocating the result to a pointer. How is it supposed to work?
EDIT now that you have updated your question with "better" code and it's still not working, here are a few things you could / should change.
You declare a variable tmp then try to access temp. Recipe for failure
You pass the entire struct imgur to the function. That means "make a copy of everything". You should really pass a pointer to the object - change the prototype to reflect that, and access the elements as imgur->height etc
You never declare the variables height and width in your MirrorVertical function
(minor) you compute the value height - 1 - y twice per inner loop - 20000 times in total. If you swap the inner and outer loops and compute it just once (and assign to a new variable newY) you can save a little bit of time (not sure it it's really more efficient since you end up looping over X which might destroy cache coherence instead, especially with big images).
My compiler (and the C standard) complains about the statement int maxColor = 256; in the definition of the struct; you cannot initialize a value in the typedef.
Miscellaneous other errors thrown by the compiler.
I took the liberty of fixing many of them - that leads to the following code which appears to compile and run; now all you need is add your "input image" and "output image" functions (maybe).
#include <stdio.h>
//Setting the struct up for the pixels
struct pixel
{
unsigned char red;
unsigned char green;
unsigned char blue;
};
//Setting the struct up for the Image Type and scanning in the pixels into an array
struct ImageType
{
char ppImage[3];
char comment[256];
char newlinechar;
int width;
int height;
int maxColor; // cannot initialize this here; removed "=256"
struct pixel image[100][100];
};
//Function in order to flip the image, going from the left most pixel flipping with the right most
void MirrorVertical(struct ImageType *imgur) // using a pointer to the struct
{
int x,y, height, width; // added declaration of height, width
// const int middle = imgur->width / 2; // removed, not used
struct pixel tmp; // use same name here and in loop
height = imgur->height; // initialize once - save a redirect later
width = imgur->width; // ditto
for(y = 0; y < imgur->height/2; y++) // made this the outer loop
{
int newY = height - y - 1; // so we only compute it once
for(x=0; x < imgur->width; x++)
{
tmp = imgur->image[x][y]; // use "tmp" not "temp"
imgur->image[x][y] = imgur->image[x][newY];
imgur->image[x][newY] = tmp;
}
}
}
// a simple main program… this doesn't really do anything except call the function
int main(void) {
struct ImageType i1;
// … need to add code to import the image
MirrorVertical(&i1); // note - passing POINTER to i1, not the entire struct
// … need to add code to export the image
}
Let me know if that works.

Access violation reading location location 0x1D5C4C2F

This function is throwing an access violation when reading raw pixel values and I can't figure out why.
Can consider this as the only part of my code running, I've run this solo with the same result.
string filenames[]={"firstclick.raw", "secondclick.raw","thirdclick.raw","fourthclick.raw","fifthclick.raw","sixthclick.raw","seventhclick.raw","eighthclick.raw"};
FILE *file;
int height= 750, width = 453, bbp=3;
unsigned char ****images;
images = (unsigned char ****)malloc(sizeof(unsigned char ***)*8);
for(int j = 0; j<8; j++){
images[j] = (unsigned char ***)malloc(sizeof(unsigned char**)*height);
for(int i = 0; i<height; i++){
images[j][i]= (unsigned char **)malloc(sizeof(unsigned char*)*width);
for(int k = 0; k<bbp; k++)
images[j][i][k]= (unsigned char *)malloc(sizeof(unsigned char)*bbp);
}
}
for (int i = 0; i<8; i++){
if (!(file=fopen(filenames[i].c_str(),"rb"))){
cout << "Cannot open file: "<<filenames[i].c_str() <<endl;
exit(1);
}
fread(images[i], sizeof(unsigned char), height*width*bbp, file);
fclose(file);
}
The problem here is you've allocated each element of your array as a separate array (somewhere else in memory, whose location is kept as a pointer). But when you read in, you assume that it's a single contiguous block. You will overwrite all those pointers, and overflow the buffer to boot.
If you want images to be a set of discrete blocks of memory, allocate like this:
unsigned char ** images;
int i;
images = malloc( sizeof(unsigned char *) * 8 );
for( i = 0; i < 8; i++ ) {
images[i] = malloc( width * height * bpp );
}
Note that sizeof(unsigned char) is defined by the standard to always be 1. You don't need to multiply by sizeof(unsigned char) all the time.
Now, to get a pixel address in an image, you need to multiply out (usually row-major):
unsigned char * pixel = images[i] + (y * width + x) * bpp;
unsigned char r = pixel[0];
unsigned char g = pixel[1];
unsigned char b = pixel[2];
when you allocate the memory blocks in different locations in memory an fread on that structure will not work.
instead allocate one big block then set the pointers to point inside the block, that way you can use fread on it.

2d array of struct -- malloc() and free()

#pragma pack(push, 1)
typedef struct
{
/*...*/
unsigned int dataoffset; //No of bytes before actual pixel data
}HEADER;
typedef struct
{
/*...*/
unsigned int width;
unsigned int height;
unsigned short bits_per_pixel; //code is written for 24 bits only and No other format is supported..
/*...*/
}INFO_HEADER;
typedef struct
{
unsigned char b;
unsigned char g;
unsigned char r;
}COLORMAP;
#pragma pack(pop)
int main()
{
// Var decl.
INFO_HEADER *pHeader = NULL;
FILE *pImage;
COLORMAP **ppColors;
/*...*/
/* File opened in read, binary mode, memory allocated for pHeader*/
fread (pHeader, sizeof(INFO_HEADER), 1, pImage);
/*Next block is actually problematic.. Posting 'as is' from my code*/
ppColors = (COLORMAP**)malloc((pHeader -> height ) * sizeof(COLORMAP));
for(i = 0 ; i < pHeader -> height ; i++)
ppColors[i] = (COLORMAP*)malloc(pHeader -> width * sizeof(COLORMAP));
fseek(pImage, pHeader -> fileheader.dataoffset, SEEK_SET);
for (i = 0 ; i < pHeader -> width ; i++)
{
for (j = 0 ; j < pHeader -> height ; j++)
{
fread(&b, sizeof(unsigned char), 1, pImage);
fread(&g, sizeof(unsigned char), 1, pImage);
fread(&r, sizeof(unsigned char), 1, pImage);
ppColors[i][j].b = b;
ppColors[i][j].g = g;
ppColors[i][j].r = r;
printf("width = %d height = %d %d:\t", i, j, cnt);
printf("%d ", (int)ppColors[i][j].b);
printf("%d ", (int)ppColors[i][j].g);
printf("%d\n", (int)ppColors[i][j].r);
cnt++;
}
}
/*And at last free()ing..*/
for(i = 0 ; i < pHeader -> height ; i++) free(ppColors[i]);
free(ppColors);
cleanup();
return(0)
}
Possible Duplicate: http://stackoverflow.com/questions/1568042/optimal-way-to-free-a-malloced-2d-array-in-c
Though above link could not solve my problems.
I run out of memory. I have malloc()ed for height, then for each of the height, width is again malloc()ed. I am trying to work on width X height domain only. It seems that problem is with height. If you change
ppColors = (COLORMAP**)malloc((pHeader -> height ) * sizeof(COLORMAP)); to
ppColors = (COLORMAP**)malloc((pHeader -> height + 6 ) * sizeof(COLORMAP));
Then this problem disappears.
But then at the time of free()ing I get double free / corruption at core dump.
I am damn sure I am going wrong somewhere. I do not expect someone to correct my code and I just run it. Just hints would do.
A pointer to a pointer is not the same as an array of arrays.
When using a pointer-to-pointer to simulate a multi-dimensional array, like this declaration:
char **pointer;
the memory looks like this:
+------------+------------+-----+-------------------+
| pointer[0] | pointer[1] | ... | pointer[size - 1] |
+------------+------------+-----+-------------------+
| | |
v v v
Data Data Data
While a proper multi-dimensional array
char array[X][Y];
looks like this in memory:
+-------------+-------------+-----+-----------------+-------------+-----+
| array[0][0] | array[0][1] | ... | array[0][Y - 1] | array[1][0] | ... |
+-------------+-------------+-----+-----------------+-------------+-----+
So in a proper multi-dimensional array all the memory is in one single block, while using pointer-to-pointer you have an array of pointers and not an array of arrays.
So what you should do is allocate all sub-arrays separately:
ppColors = malloc(pHeader->height * sizeof(COLORMAP *));
/* Note how I allocate the width times the size of a COLORMAP pointer */
for (int i = 0; i < pHeader->height; i++)
ppColors[i] = malloc(pHeader->width * sizeof(COLORMAP));
Don't forget that you now have to call free in a loop too!
I can see a couple of problems:
ppColors is an array of pointers. Each element in the array is a COLORMAP* so you need to calculate the size to be malloced using numElements * sizeof(COLORMAP*). COLORMAP is just 3 chars so its likely that sizeof(COLORMAP*) > sizeof(COLORMAP). Your current allocation will be too small so you'll end up writing beyond the end of the array; this has undefined effects but is likely to crash.
use of width & height are reversed between allocations and loops so you'll end up writing to unallocated memory at some point in your loops.
This may not be an answer but probably help you along with other answers.
This might be problem with fread check what do you get in pHeader -> height and pHeader -> width
Use parenthesis around pHeader -> width in malloc(pHeader -> width * sizeof(COLORMAP))

Dynamic multidimensional array reallocation

I'm having some trouble with the realloc function.
I'm allocating a dynamic bidimensional array with this function:
Bubble ***allocBubblesMatrix(int height, int width) {
Bubble ***bubblesMatrix = (Bubble***) malloc(height * sizeof(Bubble**));
assert(bubblesMatrix != NULL);
int i;
for (i = 0; i < height; ++i) {
bubblesMatrix[i] = (Bubble**) malloc(width * sizeof(Bubble*));
assert(bubblesMatrix[i] != NULL);
}
int x, y;
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
bubblesMatrix[y][x] = newBubble(rand() % N_BUBBLES);
return bubblesMatrix;
}
wich is called with the next code:
int matrixHeight = 1,
matrixWidth = MATRIX_X_SIZE;
Bubble ***bubblesMatrix = allocBubblesMatrix(matrixHeight, matrixWidth);
This successfuly creates a bidimensional array 1* MATRIX_X_SIZE.
Then, I want to add a row or multiple rows to the matrix, so I use realloc with the following function. It's supposed to add heightIncrement rows. The problem is that sometimes it works, other it crashes de program.
void resizeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width,
int heightIncrement) {
if (heightIncrement <= 0) /* temporary */
return;
*bubblesMatrix = (Bubble***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));
assert(bubblesMatrix != NULL);
int x, y;
int newHeight = height + heightIncrement;
for (y = height; y < newHeight; ++y) {
(*bubblesMatrix)[y] = (Bubble**) malloc(width * sizeof(Bubble*));
assert((*bubblesMatrix)[y] != NULL);
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = newBubble(rand() % N_BUBBLES);
}
}
This function is called with:
while(true) {
drawBubblesMatrix(x1, y1, matrixHeight, matrixWidth, &bubblesMatrix, bubbles);
resizeBubblesMatrix(&bubblesMatrix, matrixHeight, matrixWidth, 1);
++matrixHeight;
getch();
clear_screen(1);
}
What am I doing wrong?
Function to deallocate the memory blocks previously allocated:
void freeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width) {
int y, x;
for (y = 0; y < height; ++y) {
for (x = 0; x < width; ++x) {
free((*bubblesMatrix)[y][x]);
(*bubblesMatrix)[y][x] = NULL;
}
free((*bubblesMatrix)[y]);
(*bubblesMatrix)[y] = NULL;
}
free(*bubblesMatrix);
*bubblesMatrix = NULL;
}
Thanks in advance.
EDIT
Silly me. I wasn't doing anything with the return value of realloc as the Karl Knechtel pointed out. But now the program crashes whenever I run it.
With Bart van Ingen Schenau's answer, I confirmed what I feared: I was ignoring the several independent memory blocks that I had allocated previously. I even ended up with a similar code to the one written by Bart but it continues to crash the program.
I've added the assert's to check the results of the malloc/realloc calls and yet I didn't have any luck. I'm using djgpp with Win98 and what's happening it's really odd:
Windows: Sometimes, it never crashes; others, it crashes after adding 2 rows.
MS-DOS: Crashes after adding 2 rows.
I'm gonna try to use -O3 with gcc to get additional clues. What would be a useful (and quick to learn/use) memory corruption/leak detection tool for windows? Is Purify the best solution?
Even my function to free the array is returning page faults.
Read the documentation:
The function may move the memory block to a new location, in which case the new location is returned.... A pointer to the reallocated memory block, which may be either the same as the ptr argument or a new location.
The type of this pointer is void*, which can be cast to the desired type of data pointer in order to be dereferenceable.
If the function failed to allocate the requested block of memory, a NULL pointer is returned, and the memory block pointed to by argument ptr is left unchanged.
You cannot correctly use realloc without doing something with the return value. Your code, right now, expects that realloc will always be able to reallocate the memory in such a way that the new block is in the same place. This is clearly impossible; the memory immediately after your array might be in use for something else.
There are a number of things wrong with your use of realloc.
You are passing the wrong pointer to realloc. You should pass the pointer you optained from malloc, which would be *bubblesMatrix.
The 'layout' of the matrices in your allocBubblesMatrix and resizeBubblesMatrix functions is different. In the alloc function, you allocate several independent memory blocks, but in the resize function, you treat it as one big block of memory. That will simply not work.
The correct usage would be:
void resizeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width,
int heightIncrement) {
*bubblesMatrix = (Bubble ***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));
int i;
int newHeight = height + heightIncrement;
for (i = height; i < newHeight; ++i)
(*bubblesMatrix)[i] = (Bubble**) malloc(width * sizeof(Bubble*));
int x, y;
for (y = height; y < newHeight; ++y)
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = newBubble(rand() % N_BUBBLES);
}
But this function still has some issues:
Both malloc and realloc can fail, which is not taken into account here
If heightIncrement is negative, you have a memory leak in the resize function.
I threw together a quick test case, and I have come to the conclusion that the problem you are now experiencing is not in this block of code. I created a very simple test case that replaces the Bubble objects with ints. When I do this, the reallocation completes successfully without crashing. Here is my code:
#include <malloc.h>
#include <assert.h>
int myVal = 0xDEAD;
int ***allocBubblesMatrix(int height, int width);
void resizeBubblesMatrix(int ****bubblesMatrix, int height, int width,
int heightIncrement);
int main(int argc, char **argv)
{
int matrixHeight = 1, matrixWidth = 10;
int i = 0;
int ***matrix = allocBubblesMatrix(matrixHeight, matrixWidth);
for(i = 1; i < matrixWidth; i++)
resizeBubblesMatrix(&matrix, matrixHeight, matrixWidth, 1);
printf("Complete!\n");
}
int ***allocBubblesMatrix(int height, int width) {
int ***bubblesMatrix = (int***) malloc(height * sizeof(int**));
assert(bubblesMatrix != NULL);
int i;
for (i = 0; i < height; ++i) {
bubblesMatrix[i] = (int**) malloc(width * sizeof(int*));
assert(bubblesMatrix[i] != NULL);
}
int x, y;
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
bubblesMatrix[y][x] = &myVal;
return bubblesMatrix;
}
void resizeBubblesMatrix(int ****bubblesMatrix, int height, int width,
int heightIncrement) {
if (heightIncrement <= 0) /* temporary */
return;
*bubblesMatrix = (int***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(int**));
assert(bubblesMatrix != NULL);
int x, y;
int newHeight = height + heightIncrement;
for (y = height; y < newHeight; ++y) {
(*bubblesMatrix)[y] = (int**) malloc(width * sizeof(int*));
assert((*bubblesMatrix)[y] != NULL);
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = &myVal;
}
}
The only changes I made were to replace Bubble with int, and to point all the entries in the matrix to a single int variable rather than doing even more allocation.
That means the error is either in drawBubblesMatrix() or in newBubble().
You need to reallocated each dimension separately. You cannot reallocate both dimensions at once, since each "row" was allocated individually.
*bubblesMatrix = (Bubble ***) realloc(bubblesMatrix, (height + heightIncrement) * width * sizeof(Bubble*));
needs to change to
*bubblesMatrix = (Bubble ***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));

Resources