I want to verify that I'm correctly handling risk of "Overflowing fixed-length string buffers." I'm also aware that I'm using C-style strings, which falls short of full C++ code.
Main
/*
PURPOSE:
attempt to implement, without using given/known-good code, various concepts
of c++.
one exception:
code in header fileToArray/set_cArrayTemp()
*/
//MOVED TO TOP - ELSE MY HEADERS FAIL
//boilerplate - won't have to use: std::
using namespace std;
//needed to use cout/cin
#include <iostream>
//for using system calls -
//warning: (www.cplusplus.com/forum/articles/11153/)
#include <cstdlib>
//to use strlen
#include <cstring>
//c++ headers (e.g. iostream) don't use .h extension so i am not either
//provides indentation and v spacing for logging
#include "header/logFormatter"
//reads a file to a char array
#include "header/fileToArray"
//dialog gets filename from user
#include "header/fileDialog"
//this is the (p)array that should hold all the text from the file
char *cArray;
//the name of the file to read
char *fileName;
void set_fileName(){
cout << vspace << col1 << "begin set_fileName()";
char *temp = getFileName();
cout << col2 << "tmp: " << temp;
fileName = new char[strlen(temp)];
strcpy(fileName,temp);
delete[] temp;
cout << col2 << "fileName is set: " << fileName;
cout << col1 << "end set_fileName()";
}
void set_cArray(){
cout << vspace << col1 << "begin set_cArray()";
char *temp = fileToArray(fileName);
if(temp){
cout << col2 << "tmp: " << temp;
/*FROM MAN STRCPY:
"If the destination string of a strcpy() is not large enough,
then anything might happen. Overflowing fixed-length string
buffers is a favorite cracker technique for taking complete
control of the machine."
*/
//so, this guards against overflow, yes?
cArray = new char[strlen(temp)];
strcpy(cArray,temp);
delete[] temp;
cout << col2 << "cArray is set: " << cArray;
cout << col1 << "end set_cArray()";
return;
}
cout << col2 << "fail - did not set cArray";
cout << col1 << "end set_cArray()";
}
//expect memory leaks = 0
void cleanup(){
cout << vspace << col1 << "begin cleanup()";
if(cArray){
delete[] cArray;
cout << col2 << "cArray deleted";
}
if(fileName){
delete[] fileName;
cout << col2 << "fileName deleted";
}
cout << col1 << "end cleanup()";
}
void closingMessage(){
cout << vspace << col2 << "APPLICATION COMPLETE";
}
int main(){
system("clear;");/*yes, i know (www.cplusplus.com/forum/articles/11153/)...
,but it provides focus for the moment and it is simple. */
//col0
cout << "begin main()";
set_fileName();
set_cArray();
cleanup();
closingMessage();
cout << "\nend main()";
return 0;
}
//TODO -
//1. use a doWhile so that user can run once and read many files without
//app exit.
//
//2. find way to provide init (not null/safe sate) of pointers
header (fileToArray):
//reads a file to a char array
//for using files
#include <fstream>
// user inputs a file [path]name
char *filenameTemp;
//this is the (p)array that should hold all the text from the file
char *cArrayTemp;
void set_filenameTemp(char *fileName_param){
cout << vspace << col3 << "begin set_filenameTemp()";
filenameTemp = new char[strlen(fileName_param)];
strcpy(filenameTemp,fileName_param);
cout << col4 << "file name assigned: " << filenameTemp;
cout << col3 << "end set_filenameTemp()";
}
void set_cArrayTemp(){
cout << vspace << col3 << "begin set_cArrayTemp()";
ifstream file(filenameTemp);
if(file.is_open()){
/*---------------------------------------------
source: www.cplusplus.com/doc/tutorials/files/
modified a bit*/
long begin,end,fileSize;
begin = file.tellg();
file.seekg(0,ios::end);
end = file.tellg();
fileSize = (end-begin-1);/* -1 because testing shows fileSize is always
one more than expected based on known lenght
of string in file.*/
/*---------------------------------------------*/
//cout << col4 << "bytes in file (fileSize=): " << fileSize;
cArrayTemp = new char[fileSize];
file.seekg(0,ios::beg);
file.read(cArrayTemp,fileSize);
file.close();
cout << col3 << "end set_cArrayTemp()";
return;
}
cout << col4 << "fail - file not open";
cout << col3 << "end set_cArrayTemp()";
}
//caller is responsible for memory
//may return null
char *fileToArray(char *fileName_param){
cout << vspace << col2 << "begin fileToArray()";
if(fileName_param){
cout << col3 << "file name received: " << fileName_param;
set_filenameTemp(fileName_param);
set_cArrayTemp();
delete[] filenameTemp;
cout << col2 << "end fileToArray()";
return cArrayTemp;
}
cout << col3 << "received NULL fileName_param";
cout << col2 << "end fileToArray()";
return cArrayTemp;
}
header (fileDialog):
//dialog gets filename from user
// user inputs a file [path]name
//number of chars to get from user input
static const int size = 20;//20 will do for now
/*FROM MAN STRCPY:
"If the destination string of a strcpy() is not large enough,
then anything might happen. Overflowing fixed-length string
buffers is a favorite cracker technique for taking complete
control of the machine."
*/
//so, this guards against overflow, yes?
//that is, by using getline, rather than cin >> var,
//size of array is controlled.
//caller is responsible for memory
char *getFileName(){
cout << vspace << col2 << "begin getFileName()";
char* input = new char[size];
cout << col2 << "enter filename: ";
cin.getline(input,size);
cout << col2 << "end getFileName()";
return input;
}
//NOTE:
// currently, this hardly justifies a header file - i expect to do more later.
// may eventually use this for all userdialog and rename to userDialog
header (logFormatter):
//STRICTLY FOR LOGGING
// spares me from managing chains of \n and \t
//this allows me to use indentation to show progress/flow
// making this a psuedo-debugger
//
//left-most column - col0 is imaginary/conceptual
//char col0 = "";
static const char col1[] = "\n ";//4 spaces
static const char col2[] = "\n ";//8 spaces
static const char col3[] = "\n ";// etc.
static const char col4[] = "\n ";
static const char vspace[] = "\n\n";
//NOTE: changed from using \t since default is 8 spaces