Char Array with data resetting on operations - c++

I have written a simple function which will take the file name with the extension and return both the extension and the filename minus the extension.
It is working fine but when I was testing it, I see that some where my filename is getting reset. Not always but some times.
#include <stdio.h>
#include <string.h>
#include <string>
#define EXTENSION_STR_MAX (16)
#define METADATA_STR_MAX (129)
struct meta_data_t
{
char filename[METADATA_STR_MAX];
char fileextension[EXTENSION_STR_MAX];
};
void GetFileExtMetadata(const char* fileName, char* fileExt, char* updateFileName)
{
// NULL Checks
if((NULL == fileName) || (NULL == fileExt) || (NULL == updateFileName))
{
printf("NULL :-/ \n");
return;
}
// Find the position of the last dot
char * pch = NULL;
pch = strrchr(fileName, '.');
if((NULL == pch) || (fileName == pch))
{
printf("Nope\n");
}
else
{
// Copy ot the extension
char fileextension[15];
strncpy(fileextension, (pch+1),15);
strcpy(fileExt, ".");
strcat(fileExt, fileextension);
// Remove the extension formthe filename
*pch = '\0';
strncpy(updateFileName, fileName, (METADATA_STR_MAX-1));
updateFileName[METADATA_STR_MAX-1] = 0;
}
}
int main()
{
meta_data_t test1 = {};
meta_data_t test2 = {};
meta_data_t test3 = {};
char tempfilename[METADATA_STR_MAX];
strncpy(test1.filename, "Poker Face.mp3", (METADATA_STR_MAX-1));
test1.filename[METADATA_STR_MAX-1] = 0;
strncpy(test2.filename, "Love.is.in.the.air.wma is the ext", (METADATA_STR_MAX-1));
test2.filename[METADATA_STR_MAX-1] = 0;
strncpy(test3.filename, "Crazy.ThisisatesttoCheckLength", (METADATA_STR_MAX-1));
test3.filename[METADATA_STR_MAX-1] = 0;
printf("%s \n",test1.filename);
printf("%s \n",test2.filename);
printf("%s \n\n",test3.filename);
strncpy(tempfilename, test1.filename, (METADATA_STR_MAX-1));
tempfilename[METADATA_STR_MAX-1] = 0;
GetFileExtMetadata(tempfilename, test1.fileextension, test1.filename);
printf(" BEFORE %s \n",test2.filename);
strncpy(tempfilename, test2.filename, (METADATA_STR_MAX-1));
tempfilename[METADATA_STR_MAX-1] = 0;
GetFileExtMetadata(tempfilename, test2.fileextension, test2.filename);
printf(" AFTER1 %s \n",test2.filename);
strncpy(tempfilename, test3.filename, (METADATA_STR_MAX-1));
tempfilename[METADATA_STR_MAX-1] = 0;
GetFileExtMetadata(tempfilename, test3.fileextension, test3.filename);
printf(" AFTER2 %s \n",test2.filename); // NOT GOOD
printf("%s - %s\n",test1.filename, test1.fileextension);
printf("%s - %s\n",test2.filename, test2.fileextension);
printf("%s - %s\n",test3.filename, test3.fileextension);
printf("%s \n",test1.filename);
printf("%s \n",test2.filename);
printf("%s \n",test3.filename);
return 0;
}
Result:
Poker Face.mp3
Love.is.in.the.air.wma is the ext
Crazy.ThisisatesttoCheckLength
BEFORE Love.is.in.the.air.wma is the ext
AFTER1 Love.is.in.the.air
AFTER2
Poker Face - .mp3
- .wma is the ext
Crazy - .ThisisatesttoCh
Poker Face
Crazy
I see tht the file name Love.is.in.the.air is becoming empty after I run the function for the third time. I am unable to understand why this is happening.
Any clue?
Thanks

Isn't the buffer to hold the file extension too small? It looks like it is 16 chars (EXTENSION_STR_MAX), but "Love.is.in.the.air.wma" is more than that. So you get classical buffer overrun.

Try debugging the code once and you will find your answer.
And reset the contents of "tempfilename" before copying another string into it.
Safe Coding.

Related

i have a program that takes input a string that's called search which is the target and i want to search in the csv file if the "search" is there

#include <stdio.h>
#include <string.h>
void myFgets(char str[], int n);
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("Usage: csv <csv file path>\n");
return 1;
}
else
{
char ch = ' ', search[100], dh = ' ';
int row = 1;
printf("Enter value to search: ");
myFgets(search, 100);
FILE* fileRead = fopen(argv[1], "r");
if (fileRead == NULL)
{
printf("Error opening the file!\n");
return 1;
}
while ((ch = (char)fgetc(fileRead)) != EOF)
{
char str[100];
int i = 0, pos = ftell(fileRead);
while ((dh = (char)fgetc(fileRead)) != ',')
{
str[i] = dh;
i++;
}
fseek(fileRead, pos + 1, SEEK_SET);
if (strstr("\n", str) != NULL)
{
row++;
}
if (strstr(search, str) != NULL)
{
printf("Value was found in row: %d\n", row);
break;
}
}
}
getchar();
return 0;
}
/*
Function will perform the fgets command and also remove the newline
that might be at the end of the string - a known issue with fgets.
input: the buffer to read into, the number of chars to read
*/
void myFgets(char* str, int n)
{
fgets(str, n, stdin);
str[strcspn(str, "\n")] = 0;
}
in line 39 im getting an error but idk why it seems like im doing everything fine
im trying to loop through the rows and split them by the ',' so i could check if search == to it but its not wokring
im using function strstr to compare 2 strings with each other it works fine and all but the only problem is at the dh
i did fseek after the dh so i dont write in the wrong place in the ch loop
You forgot to terminate the string.
while ((dh = (char)fgetc(fileRead)) != ',')
{
str[i] = dh;
i++;
}
str[i] = '\0'; /* add this to terminate the string */
Also it looks like if (strstr(search, str) != NULL) should be if (strstr(str, search) != NULL) to search for the value to search from the contents of the file.

Can't find what's causing access violation in array

!!!I have to stick with these functions as I'm not allowed to use any different!!!
A little explanation what I need to do: user input a search directory, then if nothing was found an error message pops up. If something is found, I create an array of one row because at least one file was found and it saves the name of found file. Then if FindNextFIle finds anything I add one row to existing array and this new row saves new found file name.
First output is direct output from the function and the second one is test output of the array to be sure that it worked correctly. Yet it doesn't work saying that memory access is violated so I can't work further.
There's probably 2 reasons why it's not working correctly:
Incorrect add of new row
incorrect print array function
Here's the main():
system("chcp 1251");
drtctrAr drctr;
drctr = createDAr();
WIN32_FIND_DATA FindFileData;
HANDLE hf;
hf = FindFirstFile(drctr.str, &FindFileData);
while (hf == INVALID_HANDLE_VALUE)
{
printf("Error opening files or no files found!\n Try changing the search directory or correct your input!\n");
return 1;
break;
}
StringArray fileNames;
int len;
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows);
len = wcslen(FindFileData.cFileName)+1;
fileNames.sym = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.sym, len, FindFileData.cFileName);
while (FindNextFile(hf, &FindFileData) != 0)
{
printf("Found file: %ls", FindFileData.cFileName);
printf("\n");
fileNames.rows++;
fileNames.str = (wchar_t**)realloc(fileNames.str, sizeof(wchar_t*) * (fileNames.rows));
int len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows-1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows-1], len, FindFileData.cFileName);
}
FindClose(hf);
freeDAr(drctr);
printSA(fileNames);
filterSA(fileNames);
freeSA(fileNames);
system("pause");
return 0;
And this is the print function in separate .cpp:
void printSA(StringArray arr)
{
printf("...........................\n");
for (int i = 0; i < arr.rows; i++)
{
for(int j=0;j<arr.sym[i];j++)
printf("Current file: %ls", arr.str[i][j]);
printf("\n");
}
}
And the array struct itself, forgot to add it:
struct StringArray
{
wchar_t** str = NULL;
wchar_t* sym = NULL;
int rows = 1;
};
I mentioned both probable reasons sadly it doesn't mean that these are the correct guess, something at the very start of allocating the array may be wrong
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows);
len = wcslen(FindFileData.cFileName)+1;
fileNames.sym = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.sym, len, FindFileData.cFileName);
This issue exists in above lines. You allocate memory for str but you don't allocate memory for *str / str[0] which is type of wchar_t*. Then you copy file name to fileNames.sym instead of fileNames.str[0], so you don't find the error at first place. Then if second file is found, you allocate memory for fileNames.str[1] and copy the file name to it. This part is correct.
So the access violation excepion happens when you try to access the content of fileNames.str[0] because it is non-allocated memory. If you print fileNames.str[1], it will success.
The following is modified version based on your presented code. It works for me. You can have a try.
#include <stdio.h>
#include <windows.h>
typedef struct StringArray
{
wchar_t** str;
int rows;
}StringArray;
void printSA(StringArray arr)
{
printf("...........................\n");
for (int i = 0; i < arr.rows; i++)
{
printf("Current file: %ls", arr.str[i]);
printf("\n");
}
}
int main()
{
system("chcp 1251");
WIN32_FIND_DATA FindFileData;
HANDLE hf;
hf = FindFirstFile(L"D:\\*.txt", &FindFileData);
while (hf == INVALID_HANDLE_VALUE)
{
printf("Error opening files or no files found!\n Try changing the search directory or correct your input!\n");
return 1;
break;
}
StringArray fileNames;
fileNames.rows = 1;
int len;
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows);
len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows - 1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows - 1], len, FindFileData.cFileName);
while (FindNextFile(hf, &FindFileData) != 0)
{
printf("Found file: %ls", FindFileData.cFileName);
printf("\n");
fileNames.rows++;
fileNames.str = (wchar_t**)realloc(fileNames.str, sizeof(wchar_t*) * (fileNames.rows));
int len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows - 1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows - 1], len, FindFileData.cFileName);
}
FindClose(hf);
printSA(fileNames);
// TODO: Free pointers
// ...
system("pause");
return 0;
}

Not able to read utf-8 characters from the file in C++ from input file

I would like to read utf-8 characters from a file in C++ program in Linux platform. In the fgets() function it returns junk characters in place of utf-8 character. input.txt has text triuöschen
#include <stdio.h>
#include <string>
int main()
{
FILE* fpointer = NULL;
std::string szFileData = "";
char cLine[1025] = "\0";
int iTrailingPointer = 0;
try {
const char* pcFileName = "input.txt";
//OPEN THE FILE IN READ MODE...
fpointer = fopen(pcFileName, "r");
if (fpointer == NULL)
{
printf("\n Error reading file %s", szFileData.c_str());
return 0;
}
//READ THE FILE DATA TILL THE END OF FILE...
while (!feof(fpointer))
{
memset(cLine, '\0', 1024);
fgets(cLine, 1024, fpointer);
iTrailingPointer = (int)strlen(cLine) - 1;
//REMOVE TRAILING SPACES AND NEWLINES...
while (cLine[iTrailingPointer] == '\n' || cLine[iTrailingPointer] == ' ' ||
cLine[iTrailingPointer] == '\t')
{
iTrailingPointer--;
}
cLine[iTrailingPointer + 1] = '\0';
szFileData = szFileData + cLine;
printf("\n szFileData: %s", szFileData.c_str());
}
fclose(fpointer);
}
catch (...) {
}
return 0;
}

Bypassing stack guard- Buffer overflow

I am taking a secure computer system course and I am very new to the subject. I am having a problem with an assignment where I need to get a shell by overflowing the buffer in a target program (target.cc). I cannot make any changes in target.cc but I can send the parameters to the target file.
here is the code.
#include <cstdio>
#include <cstring>
#include <cstdlib>
class SubStringReference
{
const char *start;
size_t len;
public:
SubStringReference(const char *s, size_t l) : start(s), len(l) { }
virtual ~SubStringReference() { }
virtual const char *getStart() const { return start; }
virtual int getLen() const { return len; }
};
void print_sub_string(const SubStringReference& str)
{
char buf[252];
if (str.getLen() >= sizeof buf)
{
// Only copy sizeof(buf) - 1 bytes plus a null
memcpy(buf, str.getStart(), sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0'; // null-terminate
}
else
{
printf("by passed mem check\n");
// The length is less than the size of buf so just string copy.
strcpy(buf, str.getStart());
buf[str.getLen()] = '\0'; // null-terminate to get just the substring
}
puts(buf);
}
int main(int argc, char **argv)
{
if (argc != 4)
{
fprintf(stderr, "Usage: %s STRING START LENGTH\n", argv[0]);
return 1;
}
const char *s = argv[1];
int total_len = strlen(s);
int start = atoi(argv[2]);
int len = atoi(argv[3]);
if (start < 0 || start >= total_len)
{
fputs("start is out of range!\n", stderr);
return 1;
}
if (len < 0 || start + len > total_len)
{
fputs("length is out of range!\n", stderr);
return 1;
}
SubStringReference str(s + start, len);
print_sub_string(str);
return 0;
}
Since this program is stackguard protected the program gets aborted before returning. Is there any other way that i can overflow the buffer and get a shell??
Thanks.
Edit - I am running this on a Qemu arm emulator with g++ compiler
The vulnerability can be exploited by overflowing the buffer and overwriting the address of str.getLen() function so as to point to the shell code. Since the canary check is done at the end of the function, shell is got before the canary is checked.

sub string in char* in c++ with strtok to the end of the row

I try to cat a string that type in char* in c++
this is my code
void DBManager::printMatched(char* line, char* fileName)
{
line = strtok(line,"Show");
char* teamAName = strtok(line," ");
char* teamACity = strtok(NULL,"-");
char* teamBName = strtok(NULL," ");
char* teamBCity = strtok(NULL,"\n");
}
and this is the text in line
"Show abcde fghij - klmnop qrstu"
this is the variable data:
teamAName = abcde
teamACity = fghij
teamBName = klmnop
teamBCity = qrs
how can i fix teamBCity i need to cut to the in of the row.
i work on Linux system.
I think this is what you want. Not entirely sure given your example. It can obviously be improved upon and maybe you want to use more c++ish facilities?
void DBManager::printMatched(char* line, char* fileName)
{
char* linecpy = strdup(line);
char* dummy = strtok(linecpy," ");
char* teamAName = strtok(NULL," ");
char* teamACity = strtok(NULL," ");
dummy = strtok(NULL," ");
char* teamBName = strtok(NULL," ");
char* teamBCity = strtok(NULL," \n");
printf("teamAName %s\n", teamAName);
printf("teamACity %s\n", teamACity);
printf("teamBName %s\n", teamBName);
printf("teamBCity %s\n", teamBCity);
// do something with strings here?
}