C invalid memory access - c

I am new to C language and I'm trying to compare the characters a pointer points. But when I inspect my code with Intel Inspector for memory errors I am getting invalid memory access errors in this function.
Inspectors says that these two lines cause this.
for (int i = 0; currentPathParameter[i] != '\0'; ++i) {
if (currentPathParameter[i] == '/')
}
Whole function:
bool asteriskControl(char* currentPathParameter) {
int directory = 1;
for (int i = 0; currentPathParameter[i] != '\0'; ++i) {
if (currentPathParameter[i] == '/')
directory++;
}
if (asteriskCounter > directory) {
printf("Can not use '*' operator for the folder that the program is currently in.");
return false;
}
return true;}
This is the line that I call the function.
noAsteriskError = asteriskControl(currentPath);
I am passing currentPath to function and I initialize it here.
char* currentPath = NULL;
char erdem[12] = { 'e','r','d','e','m','/','h','a','k','a','n','\0' };
currentPath = strdup(erdem);
Minimal code example:
int asteriskCounter = 1;
bool asteriskControl(char* currentPathParameter) {
int directory = 1;
for (int i = 0; currentPathParameter[i] != '\0'; ++i) {
if (currentPathParameter[i] == '/')
directory++;
}
if (asteriskCounter > directory) {
printf("Can not use '*' operator for the folder that the program is currently in.");
return false;
}
return true;}
int main() {
char* currentPath = NULL;
char erdem[] = "erdem/hakan";
currentPath = strdup(erdem);
bool noAsteriskError = false;
if (asteriskCounter > 0)
if (currentPath != NULL) {
noAsteriskError = asteriskControl(currentPath);
}
else {
noAsteriskError = false;
}
else {
noAsteriskError = true;
}
return 0;}
Any help is appreciated.

Related

Heap buffer overflow on a getline() - C

I am coding a local server, I need to parse a file to get the config of the server.
Problem : I have a heap buffer overflow indicated at on the while.
This probeme is shown when I run with -fsanitize but I don't have any trouble without.
Here is the code :
struct container *configParse(FILE *file)
{
char *line = NULL;
size_t n;
char *token = NULL;
char *saveptr = NULL;
struct container *head = NULL;
struct container *container = NULL;
int key = 0;
int first = 1;
while ((getline(&line, &n, file)) != -1)
{
token = strtok_r(saveptr, " =\n\r", &line);
while (token != NULL)
{
if (token[0] == '[')
{
if (first)
{
container = container_init();
container->title = token;
head = container;
first = 0;
}
else
{
container = container_add_back(container);
container = container->next;
container->item = NULL;
container->title = token;
}
key = 0;
}
else
{
if (key == 0)
{
if (container->item == NULL)
{
container->item = items_init();
container->item->key = token;
}
else
{
struct item *itemcpy = container->item;
while (itemcpy->next != NULL)
{
itemcpy = itemcpy->next;
}
itemcpy->next = items_init();
itemcpy->next->key = token;
}
key = 1;
}
else
{
struct item *itemcpy = container->item;
while (itemcpy->next != NULL)
{
itemcpy = itemcpy->next;
}
itemcpy->value = token;
key = 0;
}
}
token = strtok_r(NULL, " =\n\r", &line);
}
}
container_print(head);
printf("\n*****Parsing du .conf*****\n\n");
if (isvalid(head))
printf("Parsing OK\n");
else
{
printf("Parsing KO\n");
return NULL;
}
return head;
}
Thanks in advance.
As explained I try to run the program without -fsanitze, and everything was fine

Compare cJSON objects in the same code every time program is executed

I have a code which is always running in the background. compareContents() reads contents from a file periodically (based on an event) and stores it in a cSJON object. I have to compare current contents of the file (cJSON object) with the previous contents (again a cJSON object) everytime, but I am getting a memory leak. Please help.
cJSON * prev = NULL, *current = NULL;
bool compare = false;
bool compareJSON(cJSON *i,cJSON *j) /* referred from https://cjson.docsforge.com/master/api/cJSON_Compare/ */
{
if (i->type != j->type) {
return false;
}
if (i->type == cJSON_Number && (i->valueint != j->valueint)) {
return false;
}
if (i->type == cJSON_String && strcmp(i->valuestring,j->valuestring)){
return false;
}
if (i->type==cJSON_Array)
{
cJSON *ic = i->child, *jc = j->child;
while (ic && jc)
{
if (!compareJSON(ic, jc)) {
return false;
}
ic = ic->next, jc = jc->next;
}
if (ic || jc)
return false;
}
if (i->type == cJSON_Object)
{
cJSON *ic = i->child;
while (ic)
{
cJSON *jc = cJSON_GetObjectItem(j,ic->string);
if (!jc || !compareJSON(ic,jc)){
return false;
}
ic = ic->next;
}
// And again, for j == i.
cJSON *jc = j->child;
while (jc)
{
cJSON *ic=cJSON_GetObjectItem(i,jc->string);
if (!ic || !compareJSON(ic,jc)){
return false;
}
jc = jc->next;
}
}
return true;
}
bool compareContents(){
int fd = open("/tmp/abc.txt", O_RDONLY);
char* data = (char *)malloc(st.st_size + 1); //st.st_size obtained from fstat
int n = read(fd, data, st.st_size);
data[n] = '\0';
cJSON* root = cJSON_Parse(data);
if(prev == NULL){ //first time execution of program
prev = root;
}
else {
if(current){
prev = current;
}
}
current = cJSON_Duplicate(root,1);
if (prev && current)
{
compare = compareJSON(prev,current);
}
if (fd >= 0)
close(fd);
if (access("/tmp/abc.txt", F_OK) == 0 && remove("/tmp/abc.txt") != 0){
printf("Error deleting the file\n");
}
if (data)
free(data);
if (root)
cJSON_Delete(root);
return compare;
}
I am not sure, but this seems like dynamic copy?
current = cJSON_Duplicate(root,1);
That is you never free current and prev if it was not null. Maybe start from this point? Seems like memory leak.

Why is config_read_file() returning config_false?

I have been using libconfig for config files in a project. When I remove the double quotes from sources by source_to_use, config_read_file() returns config_true and also has a syntax error. The syntax error will cause my getter for the source_to_use option to go to the default case. Also because of this my getter for the source array, will also go to the else case. Could this just be me making a simple syntax error with the libconfig format?
This is the config file I am using:
#config for walld
#colors
colors = TRUE;
source_to_use: "sources";
default:
[
"/home/seth/Pictures/kimi.png"
];
sources:
[
"/home/seth/.walld/persona",
"/home/seth/.walld/image-urls"
];
This is the function I have reading it:
settings* read_config(const char* config_file, const char* home_dir) {
settings* options = malloc(sizeof(settings));
config_t config;
config_setting_t* setting;
const char* source;
int colors;
config_init(&config);
if (config_read_file(&config, config_file) == CONFIG_TRUE) {
config_destroy(&config);
return NULL;
}
if (config_lookup_bool(&config, "colors", &colors)) {
options->colors = colors;
}
else {
options->colors = 0;
}
if (config_lookup_string(&config, "source_to_use", &source)) {
//NOP
}
else {
source = "default";
}
setting = config_lookup(&config, source);
if (setting != NULL) {
int count = config_setting_length(setting);
linked_node* entry_point = add_node_to_list(NULL, NULL);
linked_node* current = entry_point;
options->sources = entry_point;
for (int i = 0; i < count; i++) {
char* item = config_setting_get_string_elem(setting, i);
current = add_node_to_list(current, item);
}
}
else {
options->sources = malloc(sizeof(linked_node));
int char_count = snprintf(NULL, 0, "%s%s", home_dir, "/.walld/images");
if (char_count <= 0) {
//tough luck
abort();
}
char* default_folder = malloc(char_count + 1U);
if (default_folder == NULL) {
//tough luck
abort();
}
snprintf(default_folder, char_count + 1U, "%s%s", home_dir, "/.walld/images");
options->sources->image = default_folder;
}
config_destroy(&config);
return options;
}
In your read_config function, your first if is:
if (config_read_file(&config, config_file) == CONFIG_TRUE) {
config_destroy(&config);
return NULL;
}
The sense of the if is reversed, so you'll return a NULL if the read of the file is valid.
So, you want to reverse the sense of this if:
if (config_read_file(&config, config_file) != CONFIG_TRUE) {
config_destroy(&config);
return NULL;
}
Or you could [probably] use:
if (config_read_file(&config, config_file) == CONFIG_FALSE) {

Allocation of buffer in C

I am trying to create buffer to store infinity size of symbols.
I have this structure:
typedef struct buffer {
int bufferSize;
int literalSize;
int allocatedSize;
char *bufferPtr;
} bufferStruct;
In my file.h.
I have also functions for buffer:
bufferStruct *BufferInitialize(int size) {
bufferStruct *tempBuff;
tempBuff = (bufferStruct *)malloc(sizeof(bufferStruct));
if (tempBuff == NULL) {
exit(99); // MEMORY_ERROR
}
tempBuff->bufferSize = size;
tempBuff->literalSize = 0;
tempBuff->bufferPtr = NULL;
tempBuff->allocatedSize = 0;
return (tempBuff);
}
int addToBuffer(bufferStruct *buffer, char c) {
if (buffer == NULL) {
return 99; // MEMORY_ERROR
}
if (buffer->allocatedSize > buffer->literalSize) {
buffer->bufferPtr[buffer->literalSize++] = c;
} else {
buffer->bufferPtr = realloc(buffer->bufferPtr, (buffer->allocatedSize + buffer->bufferSize) * sizeof(char));
if (buffer->bufferPtr == NULL) {
return 99; // MEMORY_ERROR
}
buffer->allocatedSize += buffer->bufferSize;
buffer->bufferSize <<= 1; // bS = bS * 2
buffer->bufferPtr[buffer->literalSize++] = c;
}
return 0;
}
int bufferDestroy(bufferStruct *buffer) {
if (buffer == NULL) {
return 99; // MEMORY_ERROR
}
free(buffer->bufferPtr);
free(buffer);
return 0;
}
In my file.c I am trying to create buffer:
token *getNextToken(token *tokenT) {
token *actualToken = NULL;
char *bufferData = NULL;
int charFromFile;
eState state = stateInit;
bufferStruct *bufferT = NULL;
while ((charFromFile = fgetc(fp))) {
switch (state) {
case stateInit: {
if (isdigit(charFromFile)) {
bufferT = BufferInitialize(8);
addToBuffer(bufferT, charFromFile);
state = stateInt;
} else
if (isalpha(charFromFile) || (charFromFile == '_')) {
state = stateId;
bufferT = BufferInitialize(16);
addToBuffer(bufferT, charFromFile);
} else
if (isspace(charFromFile)) {
state = stateInit;
... some more conditions ... it's similar, a lot.
case stateInt: {
if (isdigit(charFromFile)) {
state = stateInt;
addToBuffer(bufferT, charFromFile);
} else
if ((charFromFile == 'e') || (charFromFile == 'E')) {
state = stateExp;
addToBuffer(bufferT, charFromFile);
} else
if (charFromFile = '.') {
state = stateDouble;
addToBuffer(bufferT, charFromFile);
} else {
bufferData = bufferT->bufferPtr;
//strcpy(actualToken->content, bufferData);
addToBuffer(bufferT, '\0');
bufferDestroy(bufferT);
actualToken->type = tokenInt;
return actualToken;
}
} break;
... other similar cases ...
}
}
}
The problem is when I am trying to do this, Visual studio give me error:
One or more multiply defined symbols found
Also gives me
already defined in main.obj
for every function I have.
I don't see the way out. What am I doing wrong ?
There are multiple issues in your code:
You should not put code in header files. The function BufferInitialize should not be located in file.h unless it is defined inline.
The test while (c = fgetc(fp)) is incorrect: you use an assignment as a test expression, it is very error prone, you should at least parenthesize the assignment expression, and probably test for EOF instead of '\0': while ((c = fgetc(fp)) != EOF). Furthermore, c must be defined as an int. Post actual code, not pseudo-code.
You initialize tempBuff->bufferSize to a potentially non zero value, whereas the allocatedSize is 0 and the buffer is unallocated. This seems incorrect.
There could be many more issues in your actual code, we cannot see what the code, how can be tell you about those? Always post a complete, compilable code that demonstrates the problem.

How to free char** array that allocated in calling function from main?

this is the function that i am calling from main:
char** readTokens(char *userInput, const char *seperator)
{
char** c;
char line1[512],line2[512];
int wordCount = 0;
int index;
char* tmp;
strcpy(line1, userInput);
for (index=0;line1[index]!='\n';index++);
line1[index]='\0';
strcpy(line2,line1);
tmp = strtok(line1,seperator);
while (tmp!=NULL)
{
tmp=strtok(NULL,seperator);
wordCount = wordCount + 1;
}
if((wordCount) == ERROR)
{
return NULL;
}
c=(char**)malloc(((wordCount)+1)*sizeof(char*));
if (c == NULL)
{
printf("failed to allocate memory.\n");
return NULL;
}
tmp = strtok(line2,seperator);
index=0;
while (tmp!=NULL)
{
c[index]=(char*)malloc((strlen(tmp)+1*sizeof(char)));
if (c[index]==NULL)
{
printf("failed to allocate memory.\n");
return NULL;
}
strcpy(c[index],tmp);
tmp=strtok(NULL,seperator);
index++;
}
c[index] = NULL;//put NULL on last place
return c;
}
And this how i use it in main:
while (fgets(words, sizeof(words), filePointer) != NULL) // this line is a command of reading a line from the file.
{
/*here i am calling the function*/
array = readTokens(words, " ");
theGraph->graphEdges[index_i].sourceVertex = array[ZERO];
theGraph->graphEdges[index_i].destinationVertex = array[ONE];
theGraph->graphEdges[index_i].arcValue = atoi(array[TWO]);
for(index_j = ZERO ; index_j < vertexes ; index_j++)
{
if(theGraph->placeInTableIndex[index_j] == NULL)
{
theGraph->placeInTableIndex[index_j] = array[ZERO];
break;
}
else if(strcmp(theGraph->placeInTableIndex[index_j],array[ZERO]) == ZERO)
break;
}
for(index_j = ZERO ; index_j < vertexes ; index_j++)
{
if(theGraph->placeInTableIndex[index_j] == NULL)
{
theGraph->placeInTableIndex[index_j] = array[ONE];
break;
}
else if(strcmp(theGraph->placeInTableIndex[index_j],array[ONE]) == ZERO)
break;
}
theGraph->graphEdges[index_i+ONE].sourceVertex = array[ONE];
theGraph->graphEdges[index_i+ONE].destinationVertex = array[ZERO];
theGraph->graphEdges[index_i+ONE].arcValue = atoi(array[TWO]);
index_i+= TWO;
//freeTokens(array);
}
I tried to do free to the array in the end of the while but it not work i still have memory leak from this function (valgrind check). i am using this function to free:
void freeTokens(char** tokens)
{
while(*tokens != NULL)
{
*tokens = NULL;
free(*tokens);
*tokens++;
}
tokens = NULL;
free(tokens);
}
You're losing the original value of tokens (the thing you need to free) by incrementing it; then you set it to NULL, then try to free NULL.
Instead:
void freeTokens(char** tokens)
{
char **freeTokens = tokens;
while (*freeTokens != NULL)
{
free(*freeTokens);
*freeTokens = NULL; // not actually necessary, but must happen *after* if at all
freeTokens++;
}
free(tokens);
// tokens = NULL; // accomplishes nothing; doesn't change the caller's version
}

Resources