Segmentation Fault While Reading File in C - c

I am still very new to the c language and I am playing with reading files for the first time. I had similar code to this code which used to run perfectly fine but now I am running into issues. I keep getting the error Segmentation fault (core dumped) every time I try to run this program.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct student {
char first[30];
char last[30];
char ssn[9];
};
void make_arrays() {
FILE *fp = fopen("students.db", "r");
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
fseek(fp, 0, SEEK_SET);
long num_students = size / sizeof(struct student);
printf("There are %ld students in the file", num_students);
fclose(fp);
}
int main(int argc, char **argv[]) {
make_arrays();
return 0;
}

The segmentation fault might be caused by fopen failing to open the file.
You should always test for such failures and exit with an informative message.
Also note that, if the file is indeed binary, it should be open in binary mode to avoid end of line translation:
FILE *fp = fopen("students.db", "rb");
Also change the prototype for main to int main(int argc, char *argv[]) or simply int main(). There are too many stars in char **argv[].

You don't have to mark my answer as accepted, just want to inspire people to write code so that it is readable and safe. Don't be lazy to write code like this where quality is a factor.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
struct student /* Magic numbers everywhere */
{
char first[30];
char last[30];
char ssn[9];
};
void* handle_nullptr_error (void* ptr, char *action, int code)
{
if(ptr == NULL)
{
fprintf(stderr, "Failed to %s\n", action);
exit(code);
}
printf("Succeeded to %s\n", action);
return ptr;
}
int handle_nonzero_error (int val, char *action, int code)
{
if(val != 0)
{
fprintf(stderr, "Failed to %s\n", action);
exit(code);
}
printf("Succeeded to %s\n", action);
return val;
}
int handle_negval_error (int val, char *action, int code)
{
if(val < 0)
{
fprintf(stderr, "Failed to %s\n", action);
exit(code);
}
printf("Succeeded to %s\n", action);
return val;
}
/** This function is not guaranteed to be portable and work (but it will at least fail properly),
* because not all systems and/or library implementations support `SEEK_END` in files
* opened in text mode, as specified by #mode
* Moreover, in binary mode it will behave in an undefined manner, because different systems
* may store files data completely differently. In most cases it will succeed, just don't
* write code that crashes if not.
*/
long int get_file_charcount (const char *filename, char* mode)
{
FILE* fp = NULL;
long int fpSize = 0L;
/* Alignment for complicated function calls (for e.g where functions are passed as arguments) */
fp = handle_nullptr_error (fopen(filename, mode), "open file.", 1);
(void)handle_nonzero_error (fseek(fp, 0, SEEK_END), "seek end position.", 2);
fpSize = handle_negval_error (ftell(fp), "tell position.", 3);
fclose(fp); /* - May fail, as well */
return fpSize;
}
/** This function depends on POSIX headers and it is unix-conformant, although there are still
* some exceptions.
*
* Note that the value returned is the length of the contents of the symbolic link,
* and does not count any trailing null pads. The value is ought to be system-specific.
*/
_off64_t get_file_size (const char *filename)
{
struct stat st = {0};
(void)handle_negval_error(stat(filename, &st), "get file size.", (-1));
return st.st_size;
}
/** A validation function should first determine whether file's size is
* actually dividable by `sizeof(struct STUDENT_DESCRIPTION);`.
*
* Further more you can use `get_file_size()` as an alternative to
* `get_file_charcount()`. In the latter case, make sure you to specify the
* appropriate mode, "r" for text files and "rb" for binary files.
*/
void make_arrays ()
{
long int size = get_file_charcount("myfile.txt", "r");
long int num_students = size / sizeof(struct STUDENT_DESCRIPTION);
printf("size of file: %ld\n", size);
printf("There are %ld students in the file", num_students);
}
int main (void)
{
make_arrays();
return EXIT_SUCCESS;
}

Related

Writing to file in C overwrites variables

Description:
I have created a small program that stores the name and checksum of a file in a struct, for each file in a directory. When output is written to stdout with printf, everything seems fine, but if we write to a file with either fputs or fprintf, values get overwritten, perhaps because of some buffer overflow?
Output from main with print.
Name: 2.txt. Checksum: fc769d448ed4e08bd855927bad2c8e43efdf5315a6daa9f28577758786d52eaf
Name: 1.txt. Checksum: 2d46cffd0302c5537ddb4952a9cca7d66060dafecd56fe3a7fe8e5e5cabbbbf9
Name: 3.txt. Checksum: 37bb2e5563e94eee68fac6b07501c44f018599482e897a626a94dd88053b4b7e
However, if we print the values of checksumMaps[0] to a file,
the value checksumMaps[0].filename gets overwritten (with the last 2 bytes of the checksum string) as seen by:
FILE *fp = fopen("mychecksums.txt", "w");
char formatted_bytes[32*2+1];
char *filename = checksumMaps[0].filename;
format_bytes(formatted_bytes, checksumMaps[0].checksum);
fputs(filename, fp);
fputs(formatted_bytes, fp);
// We print the value of `filename` again in order to see that it has been overwritten.
printf("%s \n", filename);
fclose(fp);
The program writes aftxt to stdout instead of 2.txt.
Using gdb, I can see that the value of filename changes from 2.txt to aftxt after the line fputs(formatted_bytes, fp);. What could be the reason for this?
Minimal Reproducible Example
ArchiveFile.h
typedef struct ArchiveFile{
char *uuid;
char *checksum;
char *relative_path;
int is_binary;
} ArchiveFile;
typedef struct file_content{
unsigned char* bytes;
unsigned long file_size;
} file_content;
void set_uuid(ArchiveFile *file, char* uuid);
char* get_absolute_path(ArchiveFile *file, char* root);
char* get_file_text(ArchiveFile *file, char* root);
void get_bytes(ArchiveFile *file, char* root, unsigned char *buffer, size_t fsize);
long get_file_size(ArchiveFile *file, char *root);
ArchiveFile.c
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include "ArchiveFile.h"
#include <string.h>
void set_uuid(ArchiveFile* file, char* uuid){
file->uuid = uuid;
}
char* get_absolute_path(ArchiveFile *file, char* root){
/* Allocate space according to the relative path +
the root path + null terminating byte.*/
char* absolute_path = malloc(strlen(file->relative_path) + strlen(root) + 1);
// Add the root path.
strcpy(absolute_path, root);
// Concatonate the root with the rest of the path.
strcat(absolute_path, file->relative_path);
return absolute_path;
}
char* get_file_text(ArchiveFile *file, char* root){
char* absolute_path = get_absolute_path(file, root);
FILE *fp = fopen(absolute_path, "r");
if(fp == NULL)
printf("Could not open file %s \n", absolute_path);
// Platform independent way of getting the file size in bytes.
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
fseek(fp, 0, SEEK_SET); /* same as rewind(f); */
char *buffer = malloc(fsize);
if(fp){
fread(buffer, sizeof(char), fsize, fp);
}
fclose(fp);
free(absolute_path);
return buffer;
}
void print_bytes2(unsigned char* md, size_t size){
for (size_t i = 0; i < size; i++) {
printf("%02x ", md[i]);
}
printf("\n");
}
void get_bytes(ArchiveFile *file, char *root, unsigned char *buffer, size_t fsize){
char* absolute_path = get_absolute_path(file, root);
FILE *fp = fopen(absolute_path, "rb");
if(fp){
fread(buffer, 1, fsize, fp);
}
free(absolute_path);
fclose(fp);
}
long get_file_size(ArchiveFile *file, char *root){
char* filepath = get_absolute_path(file, root);
FILE *fp = fopen(filepath, "rb");
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
fseek(fp, 0, SEEK_SET); /* same as rewind(f); */
free(filepath);
fclose(fp);
return fsize;
}
checksum/checksum.h
// Used to store information about filename and checksum.
typedef struct ChecksumMap{
char* filename;
unsigned char checksum [32];
} ChecksumMap;
int calculate_checksum(void* input, unsigned long length, unsigned char* md);
checksum/checksum.h
#include <stdio.h>
#include <openssl/sha.h>
#include "checksum.h"
int calculate_checksum(void* input, unsigned long length, unsigned char* md){
SHA256_CTX context;
if(!SHA256_Init(&context))
return 0;
if(!SHA256_Update(&context, (unsigned char*)input, length))
return 0;
if(!SHA256_Final(md, &context))
return 0;
return 1;
}
main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/types.h>
#include "ArchiveFile.h"
#include "checksum/checksum.h"
void format_bytes(char* buffer, unsigned char* md){
for (int i = 0; i < 32; i++) {
sprintf(&buffer[i*2], "%02x", md[i]);
}
buffer[32*2] = '\0';
}
void *listdir(char *name, int count, ChecksumMap *checksumMaps)
{
DIR *dir;
struct dirent *direntry;
if (!(dir = opendir(name)))
return NULL;
while ((direntry = readdir(dir)) != NULL) {
// If we reach a directory (that is not . or ..) then recursive step.
if (direntry->d_type == DT_DIR) {
char path[1024];
if (strcmp(direntry->d_name, ".") == 0 || strcmp(direntry->d_name, "..") == 0)
continue;
snprintf(path, sizeof(path), "%s/%s", name, direntry->d_name);
listdir(path, count, checksumMaps);
} else {
unsigned char md[32];
ArchiveFile file;
file.relative_path = direntry->d_name;
// Get the full path of the file:
char parent_name[strlen(name)+1];
memset(&parent_name[0], 0, sizeof(parent_name));
strcat(parent_name, name);
strcat(parent_name, "/");
size_t fsize = get_file_size(&file, parent_name);
unsigned char *bytes = malloc(sizeof(char) * fsize);
get_bytes(&file, parent_name, bytes, fsize);
calculate_checksum((void*) bytes, fsize, md);
ChecksumMap checksumMap = {.filename=file.relative_path};
memcpy(checksumMap.checksum, md,
sizeof(checksumMap.checksum));
free(bytes);
}
}
closedir(dir);
return NULL;
}
int main(int argc, char const *argv[]) {
FILE *fp = fopen("mychecksums.txt", "w");
char formatted_bytes[32*2+1];
char *filename = checksumMaps[0].filename;
format_bytes(formatted_bytes, checksumMaps[0].checksum);
fputs(filename, fp);
fputs(formatted_bytes, fp);
// We print the value of `filename` again in order to see that it has been overwritten.
printf("%s \n", filename);
fclose(fp);
}
Compile with gcc:
gcc -Wall -Wextra main.c ArchiveFile.c checksum/checksum.c -lcrypto
The program writes aftxt to stdout instead of 2.txt. Using gdb, I can see that the value of filename changes from 2.txt to aftxt after the line fputs(formatted_bytes, fp);. What could be the reason for this?
Hard to say, because we're in the domain of UB (undefined behavior). But there are two obvious candidates here.
formatted_bytes is not properly terminated, causing fputs to read past the array, invoking UB.
fp is not a valid stream. The reason could be that it's not initialized, or changed, or the stream is closed or something.
Enable -Wall -Wextra -fsanitize=address. You could also try -fsanitize=undefined.
Check all return values. malloc, fopen and fputs returns a value that can be used for error checking.
Replace formatted_bytes with a hardcoded string that have the value you think it has.
Learn how to create a Minimal, Reproducible Example and how to debug small c programs. It's a guide I wrote a while ago.
Update
It seems that there was some different problems with the code.
First thing to notice is file.relative_path = direntry->d_name;, however the value that direntry points to changes in each iteration, thus the value file.relative_path points to, also changes. Furthermore, the size of the string stored in file.relative_path has never been specified, which would be a problem, if we use strcpy.
The solution is to specify a size for file.relative_path and use strcpy to copy the value of direntry->d_name. Also, no need for the checksumMap struct, since ArchiveFile already can store the same information (again, specify a size for the checksum).
Thing to keep in mind when you work with strings, buffers, arrays in C:
Remember that strings in C are based on char arrays, themselves based on a pointer to the first element. Assigning the value of one string to another might return in unexpected behavior when you actually want to copy the value of the string, not the address to the first element.
One bug here:
char parent_name[strlen(name)+1];
memset(&parent_name[0], 0, sizeof(parent_name)); // could have been parent_name[0]='\0'; instead
strcat(parent_name, name); // Now the parent_name buffer is full and null terminated.
strcat(parent_name, "/"); // this overwrites the null terminator and writes a new one out-of-bounds
You should have done something like this:
size_t length = strlen(name);
char parent_name[length+1+1];
memcpy(parent_name, name, length); // copies characters only (fast) but not the null term
parent_name[length] = '/'; // append this single character 1 symbol past "name" string
parent_name[length+1] = '\0'; // add manual null termination

Error when passing filename per reference (C)

I need to pass a char pointer and filename per reference, and allocate a size for the pointer in that same function. (in the program it reads the size it needs to allocate from the file).
I created the file and also checked it in a hex editor, and it does exist.
I have tried to run it on GCC and Cygwin, it doesn't seem to be a compiler specific problem.
The following code is just the barebones, but still contains the same error:
GDB tells me it's a segfault caused by the file not existing. ("No such file or directory").
Where did I go wrong?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define SIZE 50
#define NAME "name"
int loadFile(char** board, char* filename);
int main(int argc, char const *argv[])
{
char* board;
char* filename = NAME;
loadFile(&board, filename);
board[49] = '\0';
return 0;
}
int loadFile(char** board, char* filename)
{
FILE* source = fopen(filename, "rb");
if(source == NULL)
{
printf("Error loading file.\n");
return -1;
}
*board = malloc(SIZE);
if(fread(*board, sizeof(char), SIZE, source) != SIZE)
{
fclose(source);
printf("Error loading file.\n");
return -2;
}
return 0;
}
Following many comments with suggestions, I have seen strange things when a constant char literal is passed:
#define NAME "name"
char* filename = NAME;
This assigns a pointer to a constant char literal to filename. Please try:
#define NAME "name"
char filename[] = NAME;
Check your status values:
rv = loadFile(&board, filename);
if (rv == -1) {
perror("Error opening file");
return 1;
}
This should (hopefully) give you an error message you can troubleshoot further. Using a const char * as an argument to fopen() should be OK.

Function mallocs a pointer and reads data into it, but caller can not access it

I have a specific problem: I have an issue when I try to use my own function to load file on memory.
load_file_on_memory() receives a filename and a pointer. It just opens the file, allocates memory dynamically for file content and fills it, and passes the pointer to the caller using destiny as an argument.
But I have a problem: Inside load_file_on_memory() function, I have success on malloc space for content. I can put data on pointer and get it, too.
When I try to use the pointer outside function, the caller just gets trash. I will post my code (shortly) here.
I can't understand why this happen. I am using Windows 7 with Tiny C Compiler. I don't know if that environment can cause errors.
Here's my source
#include <stdio.h>
#include <stdlib.h>
int load_file_on_buffer(char filename[], void *buffer_destiny){
FILE *file_loaded;
unsigned int file_size;
file_loaded = fopen(filename, "rb");
if(file_loaded == NULL)
return -1;
fseek(file_loaded, 0, SEEK_END);
file_size = ftell(file_loaded);
fseek(file_loaded, 0, SEEK_SET);
buffer_destiny = (void *) malloc(file_size);
fread((char *) buffer_destiny, file_size, 1, file_loaded);
printf("BEGIN DEBUG FILE\n");
printf("%s", buffer_destiny);
printf("\n\nEND DEBUG FILE\n");
fclose(file_loaded);
return 0;
}
int main(int argc, char *argv[]){
char *buffered_input_file;
///First, load input file
if(load_file_on_buffer("test.txt", (void *)buffered_input_file) != 0)
return -1;
printf("Input file loaded successfully\n");
printf("This function must print file content: \n\n");
printf("%s", buffered_input_file);
}
You are passing a parameter void* buffer_destiny. Once the function is entered, this is just a normal variable. Which you overwrite using a malloc () call. This has no effect on the calling function. Instead declare the function as
int load_file_on_buffer(char filename[], void **pbuffer_destiny)
call it as
void* buffered_input_file;
load_file_on_buffer("test.txt", &buffered_input_file)
and in the function write
void* buffer_destiny = malloc (...);
*pbuffer_destiny = buffer_destiny;
The pointer buffer_destiny is a local variable in the function load_file_on_buffer. Changing buffer_destiny has no effect on the pointer buffer_input_file in main. One way to fix the problem is to return the pointer to main.
Another problem is that you're using "%s" to print the files content. In order for that to work, you need to properly NUL terminate the buffer. In other words, the buffer needs to be one byte bigger than the file size and a NUL terminator '\0' needs to be placed in that extra byte.
#include <stdio.h>
#include <stdlib.h>
char *load_file_on_buffer( const char *filename )
{
FILE *file_loaded;
unsigned int file_size;
file_loaded = fopen(filename, "rb");
if(file_loaded == NULL)
return NULL;
fseek(file_loaded, 0, SEEK_END);
file_size = ftell(file_loaded);
fseek(file_loaded, 0, SEEK_SET);
char *buffer_destiny = malloc(file_size + 1);
fread( buffer_destiny, file_size, 1, file_loaded );
buffer_destiny[file_size] = '\0';
printf("BEGIN DEBUG FILE\n");
printf("%s", buffer_destiny);
printf("\n\nEND DEBUG FILE\n");
fclose(file_loaded);
return buffer_destiny;
}
int main(int argc, char *argv[])
{
char *buffered_input_file;
///First, load input file
if( (buffered_input_file = load_file_on_buffer("test.txt")) == NULL )
return -1;
printf("Input file loaded successfully\n");
printf("This function must print file content: \n\n");
printf("%s", buffered_input_file);
}
If you still want to pass the buffered_input_file as a parameter then this will work for you, I commented the code at some parts I believe clarification is required.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int load_file_on_buffer(char filename[], void **buffer_destiny)
{
FILE *file_loaded;
unsigned int file_size;
if (buffer_destiny == NULL)
return -1;
*buffer_destiny = NULL; /* to check in the calling function */
file_loaded = fopen(filename, "r"); /* rb is no longer needed in new code */
if(file_loaded == NULL)
return -1;
fseek(file_loaded, 0, SEEK_END);
file_size = ftell(file_loaded);
fseek(file_loaded, 0, SEEK_SET);
*buffer_destiny = malloc(1 + file_size); /* +1 for the null terminator */
if (*buffer_destiny == NULL)
{
fclose(file_loaded);
return -1;
}
/* add a null terminator so the string is acceptable by printf */
memset(*buffer_destiny + file_size, '\0', 1);
/* you got this wrong
*
* fread((char *) buffer_destiny, file_size, 1, file_loaded);
*
* the correct way is
*
* fread(void *ptr, size_t size, size_t count, FILE *fp);
*
* where size is the size of each element and count is the number of elements.
*/
if (fread(*buffer_destiny, 1, file_size, file_loaded) != file_size)
{
free(*buffer_destiny);
*buffer_destiny = NULL;
fclose(file_loaded);
return -1;
}
printf("BEGIN DEBUG FILE\n");
printf("%s", (char *)*buffer_destiny);
printf("END DEBUG FILE\n");
fclose(file_loaded);
return 0;
}
int main(int argc, char *argv[])
{
char *buffered_input_file;
if (load_file_on_buffer("data.dat", (void **)&buffered_input_file) != 0)
return -1;
printf("Input file loaded successfully\n");
printf("This function must print file content: \n\n");
printf("%s", buffered_input_file);
free(buffered_input_file);
return 0;
}
buffered_input_file is NULL initially in main() and passed to load_file_on_buffer() by value. buffer_destiny initially got NULL from main() but inside function after memory allocation it should behave normally as you mentioned. However buffer_destiny is a local variable not a pointer for passed variable, hence at the end of function it loses its information and buffered_input_file in main() is still NULL.

C Program double free or corruption error

Currently working on a concordance program in C. When I try to run the program though, I get an error.
This is my C program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void print(char Table, int n) {
printf("%d: ", n+1); // Prints the table
}
int insert(const void *bb, const void *cc) {
return strcmp(*(const char **)bb, *(const char **)cc);
}
void empty(char *Table[]) {
strcat(Table,"NULL"); // Empties the table
}
int main(int argc, char *argv[]){
if(argc!=3){
printf("ERROR: Usage: concordance table_size"); // Errors due to not enough variables (Should be tablesize and file name)
} else {
FILE *fp; //This block opens the file user has inputted and makes the string "File_contents" set to the file's contecnts
fp = fopen(argv[2],"r");
char *file_contents;
long input_file_size;
fseek(fp, 0, SEEK_END);
input_file_size = ftell(fp);
rewind(fp);
file_contents = malloc((input_file_size + 1) * (sizeof(char)));
fread(file_contents, sizeof(char), input_file_size, fp);
fclose(fp);
file_contents[input_file_size] = 0;
char *word, *words[strlen(file_contents)/2+1];
int i, n;
for(i=0;file_contents[i];i++){
file_contents[i]=tolower(file_contents[i]); //Converts all words to lower case
}
i=0;
word = strtok(file_contents, " ,.-:;?!"); //Chars which signal end of word
while(word != NULL) {
words[i++] = word;
word = strtok(NULL, " ,.-:;?!");
}
n = i;
qsort(words, n, sizeof(*words), insert);
for(i=0; i<n; ++i){
print(words[i],i);
printf("%s\n", words[i]);
}
empty(words);
fclose(fp); // Closes open file
}
return 0;
}
And the following is the error I'm getting:
* glibc detected * concordance: double free or corruption (!prev): 0x0000000001060f010
Not sure what could be causing this error to happen. Any help on this would be great though.
You aren't calling fclose() twice. Which I suppose in turn might call free() internally. Remove the fclose() at the end of the program.
you are passing NULL as argument to strtok function. I think this may cause the problem

Segmentation Fault when accessing char array outside function but noth within

so basically, thats the code producing my segmentation fault
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CORRUPT_KEY_FILE "s64581-source-key-corrupt.bin" /* ContainsKey and IV */
#define DEBUG 1
/**
* Reads content of a given file and writes it into a buffer
*
* #param filename Path of the file to be read
* #param buffer Pointer to the buffer to write into
* #param length Variable to store the filelength into
*
* #return EXIT_FAILURE if an error occurred opening th File, otherwise EXIT_SUCCESS
*/
int readFiletoBuffer(const char* filename, unsigned char* buffer, int* length) {
int i;
if(DEBUG) printf("\n\nFunction readFileToBuffer(..) called\n");
FILE *file = fopen(filename, "rb");
if(!file) {
printf("Error opening file %s", filename);
return EXIT_FAILURE;
}
fseek(file, 0 , SEEK_END);
*length = ftell(file);
rewind(file);
if(DEBUG) printf("\tLength of File %s: %d\n",filename ,*length);
buffer = (unsigned char*) malloc(*length+1);
fread(buffer, *length, 1, file);
fclose(file);
for(i=0; i<*length; i++) printf("%d:\t%X\n",14, buffer[14]);
return EXIT_SUCCESS;
}
int main(int argc, char **argv)
{
unsigned char *tmp_char;
int tmp_length, i;
tmp_char=NULL;
readFiletoBuffer(CORRUPT_KEY_FILE, tmp_char, &tmp_length);
for(i=0; i<tmp_length; i++) printf("%d:\t%X\n",i, tmp_char[i]);
return 0;
}
Notice the two for loops printing the content of the buffer. The one inside the function works fine, the one in the main-function produces a segmentations fault. Why is that, and how could I fix this while allocating the needed memory within the function readFiletoBuffer ?
Any help is appreciated! :D
To take the char array you want from the function you have to pass a char** array as argument.
In that way your char* pointer will be returned.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CORRUPT_KEY_FILE "s64581-source-key-corrupt.bin" /* ContainsKey and IV */
#define DEBUG 1
/**
* Reads content of a given file and writes it into a buffer
*
* #param filename Path of the file to be read
* #param buffer Pointer to the buffer to write into
* #param length Variable to store the filelength into
*
* #return EXIT_FAILURE if an error occurred opening th File, otherwise EXIT_SUCCESS
*/
int readFiletoBuffer(const char* filename, unsigned char** buffer, int* length) {
int i;
if(DEBUG) printf("\n\nFunction readFileToBuffer(..) called\n");
FILE *file = fopen(filename, "rb");
if(!file) {
printf("Error opening file %s", filename);
return EXIT_FAILURE;
}
fseek(file, 0 , SEEK_END);
*length = ftell(file);
rewind(file);
if(DEBUG) printf("\tLength of File %s: %d\n",filename ,*length);
*buffer = (unsigned char*) malloc(*length+1);
fread(*buffer, *length, 1, file);
fclose(file);
for(i=0; i<*length; i++) printf("%d:\t%X\n",14, buffer[14]);
return EXIT_SUCCESS;
}
int main(int argc, char **argv)
{
unsigned char *tmp_char;
int tmp_length, i;
tmp_char=NULL;
readFiletoBuffer(CORRUPT_KEY_FILE, &tmp_char, &tmp_length);
for(i=0; i<tmp_length; i++) printf("%d:\t%X\n",i, tmp_char[i]);
return 0;
}
Here is my suggestion.
The problem is, when you call your function readFiletoBuffer with parameter tmp_char, this parameter will be copied! Your tmp_char is NULL after call this function!
You need to work with the pointer to this parameter to change it like this:
tmp_char=NULL;
readFiletoBuffer(CORRUPT_KEY_FILE, &tmp_char, &tmp_length);
So your function will look like this:
int readFiletoBuffer(const char* filename, unsigned char** buffer, int* length)

Resources