Home > Software design >  C6386 - Buffer overrun while writing to 'buffer' when using fread() function
C6386 - Buffer overrun while writing to 'buffer' when using fread() function

Time:11-14

"Warning C6386 Buffer overrun while writing to 'buffer': the writable size is 'Param(1)*Param(2)' bytes, but '4294967295' bytes might be written."

I'm writing a code to calculate a postfix expression using a stack implemented using linked lists, and I'm reading the postfix expression from a local file in binary ( fopen(filename, "rb" ) into a buffer. I get the above mentioned warning at this line of code:

fread(buffer, sizeof(char), fileLength, file);

But, I've used calloc to allocate exactly the amount of memory I'd need based on the length of the file like this:

fseek(file, 0, SEEK_END);
fileLength = ftell(file);

buffer = (char*)calloc(fileLength   1, sizeof(char));
if (!buffer) {
    perror("Can't allocate memory!\n");
    return NULL;
}

I don't understand where it got the "'4294967295' bytes might be written". Anyone care enough to explain what might be the cause, I'm a student and I'm not that much experienced with C.

Here's the entire function block:

int CalculatePostfix(double* destination, char* fileName)
{
    FILE* file = NULL;
    int fileLength = 0;
    char* buffer = NULL;
    char* currentBuffer = NULL;
    int numBytes = 0;
    char operation = 0;
    double number = 0;
    int status = EXIT_SUCCESS;;
    StackElement head = { .number = 0, .next = NULL };

    file = fopen(fileName, "rb");
    if (!file) {
        perror("Can't open file!\n");
        return -1;
    }

    fseek(file, 0, SEEK_END);
    fileLength = ftell(file);

    buffer = (char*)calloc(fileLength   1, sizeof(char));
    if (!buffer) {
        perror("Can't allocate memory!\n");
        return NULL;
    }

    rewind(file);
    fread(buffer, sizeof(char), fileLength, file);
    printf("|%s|\n", buffer);
    fclose(file);

    currentBuffer = buffer;
    while (strlen(currentBuffer) > 0) {
        status = sscanf(currentBuffer, " %lf %n", &number, &numBytes);

        if (status == 1) {
            Push(&head, number);
            currentBuffer  = numBytes;
        }
        else {
            sscanf(currentBuffer, " %c %n", &operation, &numBytes);
            status = PerformOperation(&head, operation);

            if (status != EXIT_SUCCESS) {
                free(buffer);
                while (head.next != NULL) {
                    DeleteAfter(&head);
                }
                return -1;
            }
            currentBuffer  = numBytes;
        }
    }

    free(buffer);
    return EXIT_SUCCESS;
}

CodePudding user response:

ftell returns a long integer, fread takes a size_t which, depending on implementation, often is an unsigned int. So if you happen to get -1L (which is the error return code from ftell) back from ftell you will end up vid a massive large unsigned int.

So to solve this, check return value of ftell and make sure it is not -1L, then when calling fread cast to size_t

  •  Tags:  
  • c
  • Related