From 74b8c034239386f0a470b92ceb8808edc132341e Mon Sep 17 00:00:00 2001 From: Ben Dudson Date: Mon, 10 Oct 2016 16:52:48 +0100 Subject: [PATCH 1/9] Replace vsprintf with vsnprintf Safe version, which guards against buffer overruns by specifying the length of the buffer into which text is being printed. This was used in both Output and BoutException classes to provide C printf-style output. --- include/output.hxx | 3 ++- src/sys/boutexception.cxx | 3 ++- src/sys/output.cxx | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/output.hxx b/include/output.hxx index 0233a3033e..6618296640 100644 --- a/include/output.hxx +++ b/include/output.hxx @@ -96,7 +96,8 @@ class Output : private multioutbuf_init >, static Output *instance; ///< Default instance of this class std::ofstream file; ///< Log file stream - char buffer[1024]; ///< Buffer used for C style output + static const int BUFFERLEN=1024; + char buffer[BUFFERLEN]; ///< Buffer used for C style output bool enabled; ///< Whether output to stdout is enabled }; diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index eff0ec9457..729b851cf7 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -78,7 +78,7 @@ void BoutException::Backtrace() { } else { \ char buffer[1024]; \ va_start(ap, s); \ - vsprintf(buffer, s, ap); \ + vsnprintf(buffer, s, ap); \ va_end(ap); \ for (int i=0;i<1024;++i){ \ if (buffer[i]==0){ \ @@ -100,6 +100,7 @@ BoutException::BoutException(const char* s, ...) { INIT_EXCEPTION(s); + } const char* BoutException::what() const throw() diff --git a/src/sys/output.cxx b/src/sys/output.cxx index 74a465cf83..d3da04c51c 100644 --- a/src/sys/output.cxx +++ b/src/sys/output.cxx @@ -45,7 +45,7 @@ int Output::open(const char* fname, ...) { return 1; va_start(ap, fname); - vsprintf(buffer, fname, ap); + vsnprintf(buffer, Output::BUFFERLEN, fname, ap); va_end(ap); close(); @@ -77,7 +77,7 @@ void Output::write(const char* string, ...) { return; va_start(ap, string); - vsprintf(buffer, string, ap); + vsnprintf(buffer, Output::BUFFERLEN, string, ap); va_end(ap); multioutbuf_init::buf()->sputn(buffer, strlen(buffer)); From 2d2278f9738c0c08c29d3f1458c96f92419488de Mon Sep 17 00:00:00 2001 From: Ben Dudson Date: Mon, 10 Oct 2016 16:58:50 +0100 Subject: [PATCH 2/9] More vsprintf to vsnprintf in BoutException Missed a couple of instances in BoutException derived classes. --- src/sys/boutexception.cxx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index 729b851cf7..1ee001890b 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -16,8 +16,7 @@ void BoutParallelThrowRhsFail(int &status, const char* message) { if (allstatus) throw BoutRhsFail(message); } -BoutException::~BoutException() throw() -{ +BoutException::~BoutException() throw() { } void BoutException::Backtrace() { @@ -78,7 +77,7 @@ void BoutException::Backtrace() { } else { \ char buffer[1024]; \ va_start(ap, s); \ - vsnprintf(buffer, s, ap); \ + vsnprintf(buffer,1024, s, ap); \ va_end(ap); \ for (int i=0;i<1024;++i){ \ if (buffer[i]==0){ \ From 26efa2c75be29a34e56fcec458da40b3ea96500c Mon Sep 17 00:00:00 2001 From: Ben Dudson Date: Mon, 10 Oct 2016 17:06:44 +0100 Subject: [PATCH 3/9] Make consistent BUFFER_LEN constant Both Output and BoutException now use a static const int BUFFER_LEN to control the length of the buffer used for C style output. --- include/boutexception.hxx | 2 ++ include/output.hxx | 4 ++-- src/sys/boutexception.cxx | 10 +++++----- src/sys/output.cxx | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/include/boutexception.hxx b/include/boutexception.hxx index c7542e1079..2b12445c80 100644 --- a/include/boutexception.hxx +++ b/include/boutexception.hxx @@ -19,6 +19,8 @@ public: const char* what() const throw(); void Backtrace(); protected: + static const int BUFFER_LEN = 1024; // Length of char buffer for printing + string message; }; diff --git a/include/output.hxx b/include/output.hxx index 6618296640..47eb2a6fec 100644 --- a/include/output.hxx +++ b/include/output.hxx @@ -96,8 +96,8 @@ class Output : private multioutbuf_init >, static Output *instance; ///< Default instance of this class std::ofstream file; ///< Log file stream - static const int BUFFERLEN=1024; - char buffer[BUFFERLEN]; ///< Buffer used for C style output + static const int BUFFER_LEN=1024; + char buffer[BUFFER_LEN]; ///< Buffer used for C style output bool enabled; ///< Whether output to stdout is enabled }; diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index 1ee001890b..e49847bd9a 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -75,11 +75,11 @@ void BoutException::Backtrace() { if(s == (const char*) NULL) { \ message="No error message given!\n"; \ } else { \ - char buffer[1024]; \ - va_start(ap, s); \ - vsnprintf(buffer,1024, s, ap); \ - va_end(ap); \ - for (int i=0;i<1024;++i){ \ + char buffer[BoutException::BUFFER_LEN]; \ + va_start(ap, s); \ + vsnprintf(buffer, BoutException::BUFFER_LEN, s, ap); \ + va_end(ap); \ + for (int i=0;i0 && buffer[i-1]=='\n'){ \ buffer[i-1]=0; \ diff --git a/src/sys/output.cxx b/src/sys/output.cxx index d3da04c51c..be92a0c13e 100644 --- a/src/sys/output.cxx +++ b/src/sys/output.cxx @@ -45,7 +45,7 @@ int Output::open(const char* fname, ...) { return 1; va_start(ap, fname); - vsnprintf(buffer, Output::BUFFERLEN, fname, ap); + vsnprintf(buffer, Output::BUFFER_LEN, fname, ap); va_end(ap); close(); @@ -77,7 +77,7 @@ void Output::write(const char* string, ...) { return; va_start(ap, string); - vsnprintf(buffer, Output::BUFFERLEN, string, ap); + vsnprintf(buffer, Output::BUFFER_LEN, string, ap); va_end(ap); multioutbuf_init::buf()->sputn(buffer, strlen(buffer)); From 237cf5de52007e470a254d59b1ca59f06a7a03d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Schw=C3=B6rer?= Date: Mon, 10 Oct 2016 19:00:02 +0100 Subject: [PATCH 4/9] fixing the issue with vsprintf --- include/boutexception.hxx | 4 ++-- include/datafile.hxx | 5 +++-- include/output.hxx | 13 ++++++++----- include/utils.hxx | 12 ++++++++++++ src/field/field.cxx | 9 ++++++--- src/fileio/datafile.cxx | 23 +++++++++++++---------- src/sys/boutexception.cxx | 20 ++++++++++++-------- src/sys/expressionparser.cxx | 8 +++++--- src/sys/msg_stack.cxx | 3 +-- src/sys/optionsreader.cxx | 6 ++++-- src/sys/output.cxx | 5 +++-- 11 files changed, 69 insertions(+), 39 deletions(-) diff --git a/include/boutexception.hxx b/include/boutexception.hxx index 2b12445c80..c9dba3e0a1 100644 --- a/include/boutexception.hxx +++ b/include/boutexception.hxx @@ -19,8 +19,8 @@ public: const char* what() const throw(); void Backtrace(); protected: - static const int BUFFER_LEN = 1024; // Length of char buffer for printing - + char * buffer; + int buflen; // Length of char buffer for printing string message; }; diff --git a/include/datafile.hxx b/include/datafile.hxx index 33a4274cf4..3832e8432a 100644 --- a/include/datafile.hxx +++ b/include/datafile.hxx @@ -37,7 +37,7 @@ class Datafile { public: Datafile(Options *opt = NULL); Datafile(const Datafile &other); -// ~Datafile(); Default destructor is adequate + ~Datafile(); // need to delete filename Datafile& operator=(const Datafile &rhs); @@ -77,7 +77,8 @@ class Datafile { bool shiftOutput; //Do we want to write out in shifted space? DataFormat *file; - char filename[512]; + int filenamelen; + char *filename; bool appending; int Lx,Ly,Lz; // The sizes in the x-, y- and z-directions of the arrays to be written diff --git a/include/output.hxx b/include/output.hxx index 47eb2a6fec..09853d4ec8 100644 --- a/include/output.hxx +++ b/include/output.hxx @@ -59,18 +59,21 @@ class Output : private multioutbuf_init >, public: Output() : multioutbuf_init(), std::basic_ostream(multioutbuf_init::buf()) { - + BUFFER_LEN=1024; + buffer=new char[BUFFER_LEN]; enable(); } /// Specify a log file to open Output(const char *fname) : multioutbuf_init(), std::basic_ostream(multioutbuf_init::buf()) { - + BUFFER_LEN=1024; + buffer=new char[BUFFER_LEN]; enable(); open(fname); } - ~Output() {close();} + ~Output() {close(); + delete[] buffer;} void enable(); ///< Enables writing to stdout (default) void disable(); ///< Disables stdout @@ -96,8 +99,8 @@ class Output : private multioutbuf_init >, static Output *instance; ///< Default instance of this class std::ofstream file; ///< Log file stream - static const int BUFFER_LEN=1024; - char buffer[BUFFER_LEN]; ///< Buffer used for C style output + int BUFFER_LEN; + char * buffer; ///< Buffer used for C style output bool enabled; ///< Whether output to stdout is enabled }; diff --git a/include/utils.hxx b/include/utils.hxx index 680b2a7bd4..cbacb7ca65 100644 --- a/include/utils.hxx +++ b/include/utils.hxx @@ -103,4 +103,16 @@ string trim(const string &, const string &c=" \t\r"); string trimLeft(const string &, const string &c=" \t"); string trimRight(const string &, const string &c=" \t\r"); string trimComments(const string &, const string &c="#;"); + + +#define myvsnprintf(buf,len,fmt,va) { \ + int _vsnprintflen=vsnprintf(buf,len,fmt,va); \ + if (! _vsnprintflen < len){ \ + _vsnprintflen+=1; \ + delete[] buf; \ + buf = new char[_vsnprintflen]; \ + len = _vsnprintflen; \ + vsnprintf(buf,len,fmt,va); \ + } \ + } #endif // __UTILS_H__ diff --git a/src/field/field.cxx b/src/field/field.cxx index 384caf9b6d..4fa90fe9af 100644 --- a/src/field/field.cxx +++ b/src/field/field.cxx @@ -31,6 +31,7 @@ #include #include #include +#include Field::Field() { #ifdef CHECK @@ -40,10 +41,11 @@ Field::Field() { /////////////////// PROTECTED //////////////////// -char err_buffer[512]; // Report an error occurring void Field::error(const char *s, ...) const { + int buf_len=512; + char * err_buffer=new char[buf_len]; va_list ap; // List of arguments if(s == (const char*) NULL) { @@ -51,8 +53,8 @@ void Field::error(const char *s, ...) const { }else { va_start(ap, s); - vsprintf(err_buffer, s, ap); - va_end(ap); + myvsnprintf(err_buffer,buf_len, s, ap); + va_end(ap); #ifdef TRACK output.write("Error in '%s': %s", name.c_str(), err_buffer); @@ -62,5 +64,6 @@ void Field::error(const char *s, ...) const { } throw BoutException("Error in field: %s", err_buffer); + delete[] err_buffer; } diff --git a/src/fileio/datafile.cxx b/src/fileio/datafile.cxx index 9a17005183..2de13d2ba6 100644 --- a/src/fileio/datafile.cxx +++ b/src/fileio/datafile.cxx @@ -41,13 +41,13 @@ #include #include #include - +#include #include "formatfactory.hxx" Datafile::Datafile(Options *opt) : parallel(false), flush(true), guards(true), floats(false), openclose(true), enabled(true), file(NULL) { + filename=new char[filenamelen]; if(opt == NULL) return; // To allow static initialisation - // Read options OPTION(opt, parallel, false); // By default no parallel formats for now @@ -64,7 +64,7 @@ Datafile::Datafile(const Datafile &other) : parallel(other.parallel), flush(othe enabled(other.enabled), shiftOutput(other.shiftOutput), file(NULL), int_arr(other.int_arr), BoutReal_arr(other.BoutReal_arr), f2d_arr(other.f2d_arr), f3d_arr(other.f3d_arr), v2d_arr(other.v2d_arr), v3d_arr(other.v3d_arr) { - + filename=new char[filenamelen]; // Same added variables, but the file not the same } @@ -83,18 +83,20 @@ Datafile& Datafile::operator=(const Datafile &rhs) { f3d_arr = rhs.f3d_arr; v2d_arr = rhs.v2d_arr; v3d_arr = rhs.v3d_arr; + filename = new char[filenamelen]; return *this; } -// Datafile::~Datafile() { -// } +Datafile::~Datafile() { + delete[] filename; +} bool Datafile::openr(const char *format, ...) { va_list ap; // List of arguments if(format == (const char*) NULL) return 1; va_start(ap, format); - vsprintf(filename, format, ap); + myvsnprintf(filename,filenamelen, format, ap); va_end(ap); // Get the data format @@ -130,7 +132,7 @@ bool Datafile::openw(const char *format, ...) { if(format == (const char*) NULL) return 1; va_start(ap, format); - vsprintf(filename, format, ap); + myvsnprintf(filename, filenamelen, format, ap); va_end(ap); // Get the data format @@ -173,7 +175,7 @@ bool Datafile::opena(const char *format, ...) { if(format == (const char*) NULL) return 1; va_start(ap, format); - vsprintf(filename, format, ap); + myvsnprintf(filename, filenamelen, format, ap); va_end(ap); // Get the data format @@ -522,9 +524,10 @@ bool Datafile::write(const char *format, ...) const { va_list ap; // List of arguments if(format == (const char*) NULL) return false; - char filename[512]; + int filenamelen=512; + char * filename=new char[filenamelen]; va_start(ap, format); - vsprintf(filename, format, ap); + myvsnprintf(filename, filenamelen, format, ap); va_end(ap); // Create a new datafile diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index e49847bd9a..e8f0791c44 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -8,6 +8,7 @@ #ifdef BACKTRACE #include #endif +#include void BoutParallelThrowRhsFail(int &status, const char* message) { int allstatus; @@ -17,6 +18,7 @@ void BoutParallelThrowRhsFail(int &status, const char* message) { } BoutException::~BoutException() throw() { + delete[] buffer; } void BoutException::Backtrace() { @@ -70,16 +72,18 @@ void BoutException::Backtrace() { } #define INIT_EXCEPTION(s) { \ - va_list ap; \ - \ + buflen=0; \ + buffer=NULL; \ if(s == (const char*) NULL) { \ message="No error message given!\n"; \ } else { \ - char buffer[BoutException::BUFFER_LEN]; \ - va_start(ap, s); \ - vsnprintf(buffer, BoutException::BUFFER_LEN, s, ap); \ - va_end(ap); \ - for (int i=0;i0 && buffer[i-1]=='\n'){ \ buffer[i-1]=0; \ @@ -97,7 +101,7 @@ void BoutException::Backtrace() { BoutException::BoutException(const char* s, ...) { - + INIT_EXCEPTION(s); } diff --git a/src/sys/expressionparser.cxx b/src/sys/expressionparser.cxx index 73a3c6ad65..2e03e48d88 100644 --- a/src/sys/expressionparser.cxx +++ b/src/sys/expressionparser.cxx @@ -410,13 +410,15 @@ ParseException::ParseException(const char *s, ...) { if(s == (const char*) NULL) return; - - char buffer[1024]; + + int buf_len=1024; + char * buffer= new char[buf_len]; va_start(ap, s); - vsprintf(buffer, s, ap); + myvsnprintf(buffer,buf_len, s, ap); va_end(ap); message.assign(buffer); + delete[] buffer; } const char* ParseException::what() const throw() { diff --git a/src/sys/msg_stack.cxx b/src/sys/msg_stack.cxx index 1a19709b93..203bd8bbaa 100644 --- a/src/sys/msg_stack.cxx +++ b/src/sys/msg_stack.cxx @@ -65,11 +65,10 @@ int MsgStack::push(const char *s, ...) if(s != NULL) { va_start(ap, s); - vsprintf(buffer, s, ap); + vsnprintf(buffer,MSG_MAX_SIZE, s, ap); va_end(ap); strncpy(m->str, buffer, MSG_MAX_SIZE); - m->str[MSG_MAX_SIZE] = '\0'; //output.write("Pushing '%s' -> %d\n", buffer, nmsg); }else diff --git a/src/sys/optionsreader.cxx b/src/sys/optionsreader.cxx index 46e3d85732..b3913132a3 100644 --- a/src/sys/optionsreader.cxx +++ b/src/sys/optionsreader.cxx @@ -22,10 +22,11 @@ void OptionsReader::read(Options *options, const char *file, ...) { if(file == (const char*) NULL) throw new BoutException("OptionsReader::read passed NULL filename\n"); va_list ap; // List of arguments - char filename[512]; + int buf_len=512; + char * filename=new char[buf_len]; va_start(ap, file); - vsprintf(filename, file, ap); + myvsnprintf(filename,buf_len, file, ap); va_end(ap); output.write("Reading options file %s\n", filename); @@ -35,6 +36,7 @@ void OptionsReader::read(Options *options, const char *file, ...) { parser->read(options, filename); + delete[] filename; delete parser; } diff --git a/src/sys/output.cxx b/src/sys/output.cxx index be92a0c13e..a20633b7b3 100644 --- a/src/sys/output.cxx +++ b/src/sys/output.cxx @@ -27,6 +27,7 @@ #include #include #include +#include void Output::enable() { add(std::cout); @@ -45,7 +46,7 @@ int Output::open(const char* fname, ...) { return 1; va_start(ap, fname); - vsnprintf(buffer, Output::BUFFER_LEN, fname, ap); + myvsnprintf(buffer, BUFFER_LEN, fname, ap); va_end(ap); close(); @@ -77,7 +78,7 @@ void Output::write(const char* string, ...) { return; va_start(ap, string); - vsnprintf(buffer, Output::BUFFER_LEN, string, ap); + myvsnprintf(buffer, BUFFER_LEN, string, ap); va_end(ap); multioutbuf_init::buf()->sputn(buffer, strlen(buffer)); From 12a819cbc4a91a12bdacb4479c9ba9dea077ef3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Schw=C3=B6rer?= Date: Tue, 11 Oct 2016 09:43:18 +0100 Subject: [PATCH 5/9] minor fixes --- include/utils.hxx | 7 ++++++- src/field/field.cxx | 3 --- src/fileio/datafile.cxx | 21 +++++++-------------- src/sys/boutexception.cxx | 4 ---- src/sys/expressionparser.cxx | 6 +----- src/sys/optionsreader.cxx | 3 --- src/sys/output.cxx | 10 ++-------- 7 files changed, 16 insertions(+), 38 deletions(-) diff --git a/include/utils.hxx b/include/utils.hxx index cbacb7ca65..2d69fc2e1a 100644 --- a/include/utils.hxx +++ b/include/utils.hxx @@ -106,13 +106,18 @@ string trimComments(const string &, const string &c="#;"); #define myvsnprintf(buf,len,fmt,va) { \ + va_list ap; \ + va_start(ap, fmt); \ int _vsnprintflen=vsnprintf(buf,len,fmt,va); \ - if (! _vsnprintflen < len){ \ + va_end(ap); \ + if ( _vsnprintflen+1 > len){ \ _vsnprintflen+=1; \ delete[] buf; \ buf = new char[_vsnprintflen]; \ len = _vsnprintflen; \ + va_start(va,fmt); \ vsnprintf(buf,len,fmt,va); \ + va_end(va); \ } \ } #endif // __UTILS_H__ diff --git a/src/field/field.cxx b/src/field/field.cxx index 4fa90fe9af..58b9153f4b 100644 --- a/src/field/field.cxx +++ b/src/field/field.cxx @@ -46,15 +46,12 @@ Field::Field() { void Field::error(const char *s, ...) const { int buf_len=512; char * err_buffer=new char[buf_len]; - va_list ap; // List of arguments if(s == (const char*) NULL) { output.write("Unspecified error in field\n"); }else { - va_start(ap, s); myvsnprintf(err_buffer,buf_len, s, ap); - va_end(ap); #ifdef TRACK output.write("Error in '%s': %s", name.c_str(), err_buffer); diff --git a/src/fileio/datafile.cxx b/src/fileio/datafile.cxx index 2de13d2ba6..426ac0554e 100644 --- a/src/fileio/datafile.cxx +++ b/src/fileio/datafile.cxx @@ -92,12 +92,10 @@ Datafile::~Datafile() { } bool Datafile::openr(const char *format, ...) { - va_list ap; // List of arguments if(format == (const char*) NULL) return 1; - va_start(ap, format); + myvsnprintf(filename,filenamelen, format, ap); - va_end(ap); // Get the data format file = FormatFactory::getInstance()->createDataFormat(filename, parallel); @@ -128,12 +126,10 @@ bool Datafile::openw(const char *format, ...) { if(!enabled) return true; - va_list ap; // List of arguments if(format == (const char*) NULL) return 1; - va_start(ap, format); + myvsnprintf(filename, filenamelen, format, ap); - va_end(ap); // Get the data format file = FormatFactory::getInstance()->createDataFormat(filename, parallel); @@ -171,13 +167,11 @@ bool Datafile::opena(const char *format, ...) { if(!enabled) return true; - va_list ap; // List of arguments if(format == (const char*) NULL) return 1; - va_start(ap, format); + myvsnprintf(filename, filenamelen, format, ap); - va_end(ap); - + // Get the data format file = FormatFactory::getInstance()->createDataFormat(filename, parallel); @@ -520,15 +514,14 @@ bool Datafile::write() { bool Datafile::write(const char *format, ...) const { if(!enabled) return true; - - va_list ap; // List of arguments + if(format == (const char*) NULL) return false; + int filenamelen=512; char * filename=new char[filenamelen]; - va_start(ap, format); + myvsnprintf(filename, filenamelen, format, ap); - va_end(ap); // Create a new datafile Datafile tmp(*this); diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index e8f0791c44..021fd1e5a5 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -79,10 +79,7 @@ void BoutException::Backtrace() { } else { \ buflen=BoutException::BUFFER_LEN; \ buffer = new char[buflen]; \ - va_list ap; \ - va_start(ap, s); \ myvsnprintf(buffer, buflen, s, ap); \ - va_end(ap); \ for (int i=0;i0 && buffer[i-1]=='\n'){ \ @@ -103,7 +100,6 @@ BoutException::BoutException(const char* s, ...) { INIT_EXCEPTION(s); - } const char* BoutException::what() const throw() diff --git a/src/sys/expressionparser.cxx b/src/sys/expressionparser.cxx index 2e03e48d88..a7bf4329f7 100644 --- a/src/sys/expressionparser.cxx +++ b/src/sys/expressionparser.cxx @@ -406,16 +406,12 @@ int ExpressionParser::LexInfo::getPos() { ParseException::ParseException(const char *s, ...) { - va_list ap; // List of arguments - if(s == (const char*) NULL) return; int buf_len=1024; char * buffer= new char[buf_len]; - va_start(ap, s); - myvsnprintf(buffer,buf_len, s, ap); - va_end(ap); + myvsnprintf(buffer,buf_len, s, ap); message.assign(buffer); delete[] buffer; diff --git a/src/sys/optionsreader.cxx b/src/sys/optionsreader.cxx index b3913132a3..3d396d575c 100644 --- a/src/sys/optionsreader.cxx +++ b/src/sys/optionsreader.cxx @@ -21,13 +21,10 @@ OptionsReader* OptionsReader::getInstance() { void OptionsReader::read(Options *options, const char *file, ...) { if(file == (const char*) NULL) throw new BoutException("OptionsReader::read passed NULL filename\n"); - va_list ap; // List of arguments int buf_len=512; char * filename=new char[buf_len]; - va_start(ap, file); myvsnprintf(filename,buf_len, file, ap); - va_end(ap); output.write("Reading options file %s\n", filename); diff --git a/src/sys/output.cxx b/src/sys/output.cxx index a20633b7b3..ec035231f8 100644 --- a/src/sys/output.cxx +++ b/src/sys/output.cxx @@ -40,14 +40,11 @@ void Output::disable() { } int Output::open(const char* fname, ...) { - va_list ap; // List of arguments if(fname == (const char*) NULL) return 1; - va_start(ap, fname); - myvsnprintf(buffer, BUFFER_LEN, fname, ap); - va_end(ap); + myvsnprintf(buffer, BUFFER_LEN, fname, ap); close(); @@ -72,14 +69,11 @@ void Output::close() { } void Output::write(const char* string, ...) { - va_list ap; // List of arguments if(string == (const char*) NULL) return; - va_start(ap, string); - myvsnprintf(buffer, BUFFER_LEN, string, ap); - va_end(ap); + myvsnprintf(buffer, BUFFER_LEN, string, ap); multioutbuf_init::buf()->sputn(buffer, strlen(buffer)); } From 2e05f801b20600798e83304eff81bb380efea43f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Schw=C3=B6rer?= Date: Tue, 11 Oct 2016 10:46:33 +0100 Subject: [PATCH 6/9] more fixes --- include/datafile.hxx | 1 + include/output.hxx | 11 ++++++----- include/utils.hxx | 18 +++++++++++++----- src/fileio/datafile.cxx | 5 ++++- src/sys/output.cxx | 4 ++-- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/include/datafile.hxx b/include/datafile.hxx index 3832e8432a..94552f140e 100644 --- a/include/datafile.hxx +++ b/include/datafile.hxx @@ -78,6 +78,7 @@ class Datafile { DataFormat *file; int filenamelen; + static const int FILENAMELEN=512; char *filename; bool appending; int Lx,Ly,Lz; // The sizes in the x-, y- and z-directions of the arrays to be written diff --git a/include/output.hxx b/include/output.hxx index 09853d4ec8..af50b53848 100644 --- a/include/output.hxx +++ b/include/output.hxx @@ -59,16 +59,16 @@ class Output : private multioutbuf_init >, public: Output() : multioutbuf_init(), std::basic_ostream(multioutbuf_init::buf()) { - BUFFER_LEN=1024; - buffer=new char[BUFFER_LEN]; + buffer_len=BUFFER_LEN; + buffer=new char[buffer_len]; enable(); } /// Specify a log file to open Output(const char *fname) : multioutbuf_init(), std::basic_ostream(multioutbuf_init::buf()) { - BUFFER_LEN=1024; - buffer=new char[BUFFER_LEN]; + buffer_len=BUFFER_LEN; + buffer=new char[buffer_len]; enable(); open(fname); } @@ -99,7 +99,8 @@ class Output : private multioutbuf_init >, static Output *instance; ///< Default instance of this class std::ofstream file; ///< Log file stream - int BUFFER_LEN; + static const int BUFFER_LEN=1024; ///< default length + int buffer_len; ///< the current length char * buffer; ///< Buffer used for C style output bool enabled; ///< Whether output to stdout is enabled }; diff --git a/include/utils.hxx b/include/utils.hxx index 2d69fc2e1a..43c38a013d 100644 --- a/include/utils.hxx +++ b/include/utils.hxx @@ -104,12 +104,20 @@ string trimLeft(const string &, const string &c=" \t"); string trimRight(const string &, const string &c=" \t\r"); string trimComments(const string &, const string &c="#;"); - -#define myvsnprintf(buf,len,fmt,va) { \ - va_list ap; \ - va_start(ap, fmt); \ +/// the myvsnprintf macro: +/// The first argument is an char * buffer of length len. +/// It needs to have been allocated with new[], as it may be +/// reallocated. +/// len: the length of said buffer. May be changed, mussn't be const. +/// fmt: the const char * descriping the format. +/// va: A dummy argument. will +/// note that fmt should be the first argument of the function of type +/// const char * and has to be directly followed by the variable arguments. +#define myvsnprintf(buf,len,fmt,va) { \ + va_list va; \ + va_start(va, fmt); \ int _vsnprintflen=vsnprintf(buf,len,fmt,va); \ - va_end(ap); \ + va_end(va); \ if ( _vsnprintflen+1 > len){ \ _vsnprintflen+=1; \ delete[] buf; \ diff --git a/src/fileio/datafile.cxx b/src/fileio/datafile.cxx index 426ac0554e..60e7a76455 100644 --- a/src/fileio/datafile.cxx +++ b/src/fileio/datafile.cxx @@ -45,6 +45,7 @@ #include "formatfactory.hxx" Datafile::Datafile(Options *opt) : parallel(false), flush(true), guards(true), floats(false), openclose(true), enabled(true), file(NULL) { + filenamelen=FILENAMELEN; filename=new char[filenamelen]; if(opt == NULL) return; // To allow static initialisation @@ -60,10 +61,11 @@ Datafile::Datafile(Options *opt) : parallel(false), flush(true), guards(true), f } Datafile::Datafile(const Datafile &other) : parallel(other.parallel), flush(other.flush), guards(other.guards), - floats(other.floats), openclose(other.openclose), Lx(Lx), Ly(Ly), Lz(Lz), + floats(other.floats), openclose(other.openclose), Lx(other.Lx), Ly(other.Ly), Lz(other.Lz), enabled(other.enabled), shiftOutput(other.shiftOutput), file(NULL), int_arr(other.int_arr), BoutReal_arr(other.BoutReal_arr), f2d_arr(other.f2d_arr), f3d_arr(other.f3d_arr), v2d_arr(other.v2d_arr), v3d_arr(other.v3d_arr) { + filenamelen=FILENAMELEN; filename=new char[filenamelen]; // Same added variables, but the file not the same } @@ -83,6 +85,7 @@ Datafile& Datafile::operator=(const Datafile &rhs) { f3d_arr = rhs.f3d_arr; v2d_arr = rhs.v2d_arr; v3d_arr = rhs.v3d_arr; + filenamelen=FILENAMELEN; filename = new char[filenamelen]; return *this; } diff --git a/src/sys/output.cxx b/src/sys/output.cxx index ec035231f8..09f9fafa7b 100644 --- a/src/sys/output.cxx +++ b/src/sys/output.cxx @@ -44,7 +44,7 @@ int Output::open(const char* fname, ...) { if(fname == (const char*) NULL) return 1; - myvsnprintf(buffer, BUFFER_LEN, fname, ap); + myvsnprintf(buffer, buffer_len, fname, ap); close(); @@ -73,7 +73,7 @@ void Output::write(const char* string, ...) { if(string == (const char*) NULL) return; - myvsnprintf(buffer, BUFFER_LEN, string, ap); + myvsnprintf(buffer, buffer_len, string, ap); multioutbuf_init::buf()->sputn(buffer, strlen(buffer)); } From aeacf65d23d97e89b13070d8c5abf002a20be870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Schw=C3=B6rer?= Date: Thu, 3 Nov 2016 19:05:01 +0000 Subject: [PATCH 7/9] missing static member added --- include/boutexception.hxx | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boutexception.hxx b/include/boutexception.hxx index c9dba3e0a1..359f57db34 100644 --- a/include/boutexception.hxx +++ b/include/boutexception.hxx @@ -20,6 +20,7 @@ public: void Backtrace(); protected: char * buffer; + static const int BUFFER_LEN=1024; int buflen; // Length of char buffer for printing string message; }; From a6876621adbc4d90fbd53fca9a03ed9293b439ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Schw=C3=B6rer?= Date: Wed, 16 Nov 2016 02:26:10 +0000 Subject: [PATCH 8/9] rename macro + remove dummy argument --- include/utils.hxx | 5 ++--- src/field/field.cxx | 2 +- src/fileio/datafile.cxx | 10 +++++----- src/sys/boutexception.cxx | 2 +- src/sys/expressionparser.cxx | 2 +- src/sys/optionsreader.cxx | 2 +- src/sys/output.cxx | 4 ++-- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/include/utils.hxx b/include/utils.hxx index 43c38a013d..684c989f5c 100644 --- a/include/utils.hxx +++ b/include/utils.hxx @@ -104,16 +104,15 @@ string trimLeft(const string &, const string &c=" \t"); string trimRight(const string &, const string &c=" \t\r"); string trimComments(const string &, const string &c="#;"); -/// the myvsnprintf macro: +/// the bout_vsnprintf macro: /// The first argument is an char * buffer of length len. /// It needs to have been allocated with new[], as it may be /// reallocated. /// len: the length of said buffer. May be changed, mussn't be const. /// fmt: the const char * descriping the format. -/// va: A dummy argument. will /// note that fmt should be the first argument of the function of type /// const char * and has to be directly followed by the variable arguments. -#define myvsnprintf(buf,len,fmt,va) { \ +#define bout_vsnprintf(buf,len,fmt) { \ va_list va; \ va_start(va, fmt); \ int _vsnprintflen=vsnprintf(buf,len,fmt,va); \ diff --git a/src/field/field.cxx b/src/field/field.cxx index 58b9153f4b..b63f32a058 100644 --- a/src/field/field.cxx +++ b/src/field/field.cxx @@ -51,7 +51,7 @@ void Field::error(const char *s, ...) const { output.write("Unspecified error in field\n"); }else { - myvsnprintf(err_buffer,buf_len, s, ap); + bout_vsnprintf(err_buffer,buf_len, s); #ifdef TRACK output.write("Error in '%s': %s", name.c_str(), err_buffer); diff --git a/src/fileio/datafile.cxx b/src/fileio/datafile.cxx index e64d136b62..b0ef92601e 100644 --- a/src/fileio/datafile.cxx +++ b/src/fileio/datafile.cxx @@ -44,7 +44,7 @@ #include #include "formatfactory.hxx" -Datafile::Datafile(Options *opt) : parallel(false), flush(true), guards(true), floats(false), openclose(true), enabled(true), file(NULL) { +Datafile::Datafile(Options *opt) : parallel(false), flush(true), guards(true), floats(false), openclose(true), enabled(true), shiftOutput(false), file(NULL) { filenamelen=FILENAMELEN; filename=new char[filenamelen]; if(opt == NULL) @@ -98,7 +98,7 @@ bool Datafile::openr(const char *format, ...) { if(format == (const char*) NULL) return 1; - myvsnprintf(filename,filenamelen, format, ap); + bout_vsnprintf(filename,filenamelen, format); // Get the data format file = FormatFactory::getInstance()->createDataFormat(filename, parallel); @@ -132,7 +132,7 @@ bool Datafile::openw(const char *format, ...) { if(format == (const char*) NULL) return 1; - myvsnprintf(filename, filenamelen, format, ap); + bout_vsnprintf(filename, filenamelen, format); // Get the data format file = FormatFactory::getInstance()->createDataFormat(filename, parallel); @@ -173,7 +173,7 @@ bool Datafile::opena(const char *format, ...) { if(format == (const char*) NULL) return 1; - myvsnprintf(filename, filenamelen, format, ap); + bout_vsnprintf(filename, filenamelen, format); // Get the data format file = FormatFactory::getInstance()->createDataFormat(filename, parallel); @@ -524,7 +524,7 @@ bool Datafile::write(const char *format, ...) const { int filenamelen=512; char * filename=new char[filenamelen]; - myvsnprintf(filename, filenamelen, format, ap); + bout_vsnprintf(filename, filenamelen, format); // Create a new datafile Datafile tmp(*this); diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index 35ebf4a370..49e96d13a3 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -79,7 +79,7 @@ void BoutException::Backtrace() { } else { \ buflen=BoutException::BUFFER_LEN; \ buffer = new char[buflen]; \ - myvsnprintf(buffer, buflen, s, ap); \ + bout_vsnprintf(buffer, buflen, s); \ for (int i=0;i0 && buffer[i-1]=='\n'){ \ diff --git a/src/sys/expressionparser.cxx b/src/sys/expressionparser.cxx index dde13b3e3d..825cfe5bfc 100644 --- a/src/sys/expressionparser.cxx +++ b/src/sys/expressionparser.cxx @@ -411,7 +411,7 @@ ParseException::ParseException(const char *s, ...) { int buf_len=1024; char * buffer= new char[buf_len]; - myvsnprintf(buffer,buf_len, s, ap); + bout_vsnprintf(buffer,buf_len, s); message.assign(buffer); delete[] buffer; diff --git a/src/sys/optionsreader.cxx b/src/sys/optionsreader.cxx index 5d57e63ead..7786408b1d 100644 --- a/src/sys/optionsreader.cxx +++ b/src/sys/optionsreader.cxx @@ -24,7 +24,7 @@ void OptionsReader::read(Options *options, const char *file, ...) { int buf_len=512; char * filename=new char[buf_len]; - myvsnprintf(filename,buf_len, file, ap); + bout_vsnprintf(filename,buf_len, file); output.write("Reading options file %s\n", filename); diff --git a/src/sys/output.cxx b/src/sys/output.cxx index 09f9fafa7b..7e3000dd8b 100644 --- a/src/sys/output.cxx +++ b/src/sys/output.cxx @@ -44,7 +44,7 @@ int Output::open(const char* fname, ...) { if(fname == (const char*) NULL) return 1; - myvsnprintf(buffer, buffer_len, fname, ap); + bout_vsnprintf(buffer, buffer_len, fname); close(); @@ -73,7 +73,7 @@ void Output::write(const char* string, ...) { if(string == (const char*) NULL) return; - myvsnprintf(buffer, buffer_len, string, ap); + bout_vsnprintf(buffer, buffer_len, string); multioutbuf_init::buf()->sputn(buffer, strlen(buffer)); } From 1b098901e32ef4d8e2e37a9a90c982971fcc09be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Schw=C3=B6rer?= Date: Wed, 16 Nov 2016 02:26:27 +0000 Subject: [PATCH 9/9] fix memory leak --- include/boutexception.hxx | 1 + src/field/field.cxx | 5 +++-- src/sys/boutexception.cxx | 6 ++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/boutexception.hxx b/include/boutexception.hxx index 359f57db34..c34dc6b2be 100644 --- a/include/boutexception.hxx +++ b/include/boutexception.hxx @@ -14,6 +14,7 @@ void BoutParallelThrowRhsFail(int &status, const char* message); class BoutException : public exception { public: BoutException(const char *, ...); + BoutException(const std::string); virtual ~BoutException() throw(); const char* what() const throw(); diff --git a/src/field/field.cxx b/src/field/field.cxx index b63f32a058..5dec58235b 100644 --- a/src/field/field.cxx +++ b/src/field/field.cxx @@ -59,8 +59,9 @@ void Field::error(const char *s, ...) const { output.write("Error in field: %s", err_buffer); #endif } - - throw BoutException("Error in field: %s", err_buffer); + std::string msg="Error in field: "; + msg+=err_buffer; delete[] err_buffer; + throw BoutException(msg); } diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index 49e96d13a3..4d3f11e2a8 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -101,6 +101,12 @@ BoutException::BoutException(const char* s, ...) INIT_EXCEPTION(s); } +BoutException::BoutException(const std::string msg) +{ + message="====== Exception thrown ======\n"+msg+"\n"; + + this->Backtrace(); +} const char* BoutException::what() const throw() {