From 2eb5c70147c87a47088c35258ff750d31f82b886 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Mon, 22 Apr 2019 13:52:06 +0200 Subject: [PATCH] Base::Console avoid magic numbers and enable external string size checks --- src/Base/Console.cpp | 70 ++++++++++++++++++------------------ src/Base/Console.h | 86 ++++++++++++++++++++++---------------------- 2 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/Base/Console.cpp b/src/Base/Console.cpp index ec51800014..3a970657a8 100644 --- a/src/Base/Console.cpp +++ b/src/Base/Console.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * + * (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -10,12 +10,12 @@ * for detail see the LICENCE text file. * * * * FreeCAD is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * - * License along with FreeCAD; if not, write to the Free Software * + * License along with FreeCAD; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * * USA * * * @@ -49,7 +49,7 @@ using namespace Base; //========================================================================= namespace Base { - + class ConsoleEvent : public QEvent { public: ConsoleSingleton::FreeCAD_ConsoleMsgType msgtype; @@ -141,7 +141,7 @@ ConsoleSingleton::~ConsoleSingleton() //************************************************************************** // methods -/** +/** * sets the console in a special mode */ void ConsoleSingleton::SetConsoleMode(ConsoleMode m) @@ -150,7 +150,7 @@ void ConsoleSingleton::SetConsoleMode(ConsoleMode m) _bVerbose = true; } -/** +/** * unsets the console from a special mode */ void ConsoleSingleton::UnsetConsoleMode(ConsoleMode m) @@ -165,7 +165,7 @@ void ConsoleSingleton::UnsetConsoleMode(ConsoleMode m) * The return value is an OR'ed value of all message types that have changed their state. For example * @code * // switch off warnings and error messages - * ConsoleMsgFlags ret = Base::Console().SetEnabledMsgType("myObs", + * ConsoleMsgFlags ret = Base::Console().SetEnabledMsgType("myObs", * ConsoleMsgType::MsgType_Wrn|ConsoleMsgType::MsgType_Err, false); * // do something without notifying observer myObs * ... @@ -236,10 +236,10 @@ void ConsoleSingleton::SetConnectionMode(ConnectionMode mode) } /** Prints a Message - * This method issues a Message. + * This method issues a Message. * Messages are used to show some non vital information. That means when - * FreeCAD is running in GUI mode a Message appears on the status bar. - * In console mode a message is printed to the console. + * FreeCAD is running in GUI mode a Message appears on the status bar. + * In console mode a message is printed to the console. * \par * You can use a printf like interface like: * \code @@ -251,8 +251,8 @@ void ConsoleSingleton::SetConnectionMode(ConnectionMode mode) */ void ConsoleSingleton::Message( const char *pMsg, ... ) { - char format[4024]; - const unsigned int format_len = 4024; + char format[BufferSize]; + const unsigned int format_len = BufferSize; va_list namelessVars; va_start(namelessVars, pMsg); // Get the "..." vars @@ -266,7 +266,7 @@ void ConsoleSingleton::Message( const char *pMsg, ... ) } /** Prints a Message - * This method issues a Warning. + * This method issues a Warning. * Messages are used to get the users attention. That means when * FreeCAD is in GUI mode a Message Box pops up. In console * mode a colored message is returned to the console! Don't use this carelessly. @@ -282,8 +282,8 @@ void ConsoleSingleton::Message( const char *pMsg, ... ) */ void ConsoleSingleton::Warning( const char *pMsg, ... ) { - char format[4024]; - const unsigned int format_len = 4024; + char format[BufferSize]; + const unsigned int format_len = BufferSize; va_list namelessVars; va_start(namelessVars, pMsg); // Get the "..." vars @@ -297,10 +297,10 @@ void ConsoleSingleton::Warning( const char *pMsg, ... ) } /** Prints a Message - * This method issues an Error which makes some execution impossible. - * Errors are used to get the users attention. That means when FreeCAD + * This method issues an Error which makes some execution impossible. + * Errors are used to get the users attention. That means when FreeCAD * is running in GUI mode an Error Message Box pops up. In console - * mode a colored message is printed to the console! Don't use this carelessly. + * mode a colored message is printed to the console! Don't use this carelessly. * For information purposes the 'Log' or 'Message' methods are more appropriate. * \par * You can use a printf like interface like: @@ -313,8 +313,8 @@ void ConsoleSingleton::Warning( const char *pMsg, ... ) */ void ConsoleSingleton::Error( const char *pMsg, ... ) { - char format[4024]; - const unsigned int format_len = 4024; + char format[BufferSize]; + const unsigned int format_len = BufferSize; va_list namelessVars; va_start(namelessVars, pMsg); // Get the "..." vars @@ -331,7 +331,7 @@ void ConsoleSingleton::Error( const char *pMsg, ... ) /** Prints a Message * This method is appropriate for development and tracking purposes. * It can be used to track execution of algorithms and functions. - * The normal user doesn't need to see it, it's more for developers + * The normal user doesn't need to see it, it's more for developers * and experienced users. So in normal user mode the logging is switched off. * \par * You can use a printf-like interface for example: @@ -346,8 +346,8 @@ void ConsoleSingleton::Error( const char *pMsg, ... ) void ConsoleSingleton::Log( const char *pMsg, ... ) { - char format[4024]; - const unsigned int format_len = 4024; + char format[BufferSize]; + const unsigned int format_len = BufferSize; if (_bVerbose) { @@ -373,8 +373,8 @@ const char* ConsoleSingleton::Time(void) { struct tm *newtime; time_t aclock; - time( &aclock ); // Get time in seconds - newtime = localtime( &aclock ); // Convert time to struct tm form + time( &aclock ); // Get time in seconds + newtime = localtime( &aclock ); // Convert time to struct tm form char* st = asctime( newtime ); st[24] = 0; return st; @@ -386,7 +386,7 @@ const char* ConsoleSingleton::Time(void) // Observer stuff /** Attaches an Observer to Console - * Use this method to attach a ConsoleObserver derived class to + * Use this method to attach a ConsoleObserver derived class to * the Console. After the observer is attached all messages will also * be forwarded to it. * @see ConsoleObserver @@ -703,8 +703,8 @@ PyObject *ConsoleSingleton::sPyGetStatus(PyObject * /*self*/, PyObject *args) { char *pstr1; char *pstr2; - if (!PyArg_ParseTuple(args, "ss", &pstr1, &pstr2)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "ss", &pstr1, &pstr2)) // convert args: Python->C + return NULL; // NULL triggers exception PY_TRY{ bool b=false; @@ -723,7 +723,7 @@ PyObject *ConsoleSingleton::sPyGetStatus(PyObject * /*self*/, PyObject *args) b = pObs->bMsg; else if(strcmp(pstr2,"Err") == 0) b = pObs->bErr; - + return Py_BuildValue("i",b?1:0); }PY_CATCH; } @@ -733,8 +733,8 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args) char *pstr1; char *pstr2; int Bool; - if (!PyArg_ParseTuple(args, "ssi", &pstr1, &pstr2,&Bool)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "ssi", &pstr1, &pstr2,&Bool)) // convert args: Python->C + return NULL; // NULL triggers exception PY_TRY{ ConsoleObserver *pObs = Instance().Get(pstr1); @@ -754,7 +754,7 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args) Py_INCREF(Py_None); return Py_None; } else { - Py_Error(Base::BaseExceptionFreeCADError,"Unknown Console Type"); + Py_Error(Base::BaseExceptionFreeCADError,"Unknown Console Type"); } } PY_CATCH; @@ -887,7 +887,7 @@ void ConsoleObserverStd::Log (const char *sErr) } } -RedirectStdOutput::RedirectStdOutput() +RedirectStdOutput::RedirectStdOutput() { buffer.reserve(80); } @@ -909,7 +909,7 @@ int RedirectStdOutput::sync() return 0; } -RedirectStdLog::RedirectStdLog() +RedirectStdLog::RedirectStdLog() { buffer.reserve(80); } @@ -931,7 +931,7 @@ int RedirectStdLog::sync() return 0; } -RedirectStdError::RedirectStdError() +RedirectStdError::RedirectStdError() { buffer.reserve(80); } diff --git a/src/Base/Console.h b/src/Base/Console.h index 9c290b0f1e..28e667a808 100644 --- a/src/Base/Console.h +++ b/src/Base/Console.h @@ -1,5 +1,5 @@ /*************************************************************************** - * (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * + * (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -10,18 +10,18 @@ * for detail see the LICENCE text file. * * * * FreeCAD is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * - * License along with FreeCAD; if not, write to the Free Software * + * License along with FreeCAD; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * * USA * * * * Juergen Riegel 2002 * ***************************************************************************/ - + @@ -45,11 +45,11 @@ #ifdef FC_DEBUG /// switch on the logging of python object creation and destruction -# undef FC_LOGPYOBJECTS +# undef FC_LOGPYOBJECTS /// switch on the logging of Feature update and execution -# define FC_LOGFEATUREUPDATE +# define FC_LOGFEATUREUPDATE /// switch on the logging of the Update execution through Doc, App, GuiApp and GuiDoc -# undef FC_LOGUPDATECHAIN +# undef FC_LOGUPDATECHAIN #endif ///////////////////////////////////////////////////////////////////////////////////// @@ -57,7 +57,7 @@ /** \page LogLevelPage Tag based log helpers * Simple tag based log and timing helper macros and functions. * - * \section Motivation + * \section Motivation * * FreeCAD Base::Console() is capable of outputting to different targets, and has * some basic enable/disable control of different types of logs. There is, @@ -84,7 +84,7 @@ * the same source file. * * Predefined log levels are, - * + * * \code{.c} * #define FC_LOGLEVEL_ERR 0 * #define FC_LOGLEVEL_WARN 1 @@ -118,7 +118,7 @@ * tag log levels, and \c FreeCAD.getLogLevel(tag), which outputs only integer * log level. * - * You can fine tune how the log is output by passing extra parameters to + * You can fine tune how the log is output by passing extra parameters to * #FC_LOG_LEVEL_INIT(). All the extra parameters are boolean value, which are * shown blew along with their default values. * @@ -157,7 +157,7 @@ * and \c FC_TRACE uses Base::Console().Log(), same as \c FC_LOG. These macros * checks the log level defined in \c FC_LOG_LEVEL_INIT to decide whether to * print log or not. \c msg here shall be a C++ streaming expression. End of - * line will be automatically appended by default. + * line will be automatically appended by default. * * \code * FC_ERR("error: " << code << ". exiting") @@ -171,7 +171,7 @@ * \code{.c} * void operation() { * FC_TIME_INIT(t); - * + * * //do stuff * * FC_TIME_LOG(t,"operation done."); @@ -182,7 +182,7 @@ * * \code * operation done. time: 1.12s - * \endcode + * \endcode * * Every time you call \c FC_TIME_LOG it will calculate the time duration * between this call and the last \c FC_TIME_LOG or \c FC_TIME_INIT. Time @@ -194,7 +194,7 @@ * \code{.cpp} * void operation() { * FC_TIME_INIT2(t,t1); - * + * * //do stage 1 * * FC_TIME_LOG(t1,"stage1"); @@ -234,7 +234,7 @@ * }; * * void operation1(Timing &timing) { - * + * * FC_TIME_INIT(t); * * for(...) { @@ -245,7 +245,7 @@ * FC_DURATION_PLUS(timing.d1_1,t1); * * // do step 2 - * + * * FC_DURATION_PLUS(timing.d1_2,t1); * } * @@ -255,7 +255,7 @@ * } * * void operation2(Timing &timing) { - * + * * FC_TIME_INIT(t); * * // do stuff @@ -264,7 +264,7 @@ * } * * void operation() { - * + * * Timing timing; * * FC_TIME_INIT(t); @@ -273,7 +273,7 @@ * operation1(timing); * * // do other stuff - * + * * operation2(timing); * } * @@ -285,10 +285,10 @@ * } * \endcode * - * You can also use FC_DURATION_MSG, FC_DURATION_TRACE as usual. + * You can also use FC_DURATION_MSG, FC_DURATION_TRACE as usual. * * If you use only macros provided here to do timing, the entire timing code - * can be compiled out by defining \c FC_LOG_NO_TIMING before including + * can be compiled out by defining \c FC_LOG_NO_TIMING before including * \c App/Console.h. * * \section Customization @@ -300,7 +300,7 @@ * function returns a pointer to an integer representing the log level. Python * developer or end-user can set/get the same tag based log level using * FreeCAD.setLogLevel/getLogLevel. Any change to the log level is reflected - * through the pointer returned by Base::Console().GetLogLevel(). What + * through the pointer returned by Base::Console().GetLogLevel(). What * \c FC_LOG_LEVEL_INIT(tag) does is to define a class Base::LogLevel, and then * a file static instance of that class to store the pointer to the desired tag * log level. The class and instance name is predefined. Various log macros @@ -326,7 +326,7 @@ * * You can also define your own log levels the same way. Macro * #_FC_PRINT(_instance,_l,_func,_msg) checks to see if the log shall proceed, - * where \c _instance is the static loglevel instance name (default is + * where \c _instance is the static loglevel instance name (default is * \c FC_LOG_INSTANCE), and \c _l is the log level constant to be checked, * \c _func is the Base::Console() function to print the log. * @@ -428,7 +428,7 @@ # define FC_DURATION_PLUS(...) do{}while(0) #endif //FC_LOG_NO_TIMING - + namespace Base { class ConsoleSingleton; } // namespace Base @@ -449,7 +449,7 @@ namespace Base { #endif /** The console observer class - * This class distribute the Messages issued to the FCConsole class. + * This class distribute the Messages issued to the FCConsole class. * If you need to catch some of the Messages you need to inherit from * this class and implement some of the methods. * @see Console @@ -475,7 +475,7 @@ public: /** The console class - * This class manage all the stdio stuff. This includes + * This class manage all the stdio stuff. This includes * Messages, Warnings, Log entries and Errors. The incoming * Messages are distributed with the FCConsoleObserver. The * FCConsole class itself makes no IO, it's more like a manager. @@ -495,18 +495,18 @@ class BaseExport ConsoleSingleton { public: - + static constexpr unsigned int BufferSize = 4024; // exported functions goes here +++++++++++++++++++++++++++++++++++++++ - /// Prints a Message + /// Prints a Message virtual void Message ( const char * pMsg, ... ) ; - /// Prints a warning Message + /// Prints a warning Message virtual void Warning ( const char * pMsg, ... ) ; - /// Prints a error Message + /// Prints a error Message virtual void Error ( const char * pMsg, ... ) ; - /// Prints a log Message + /// Prints a log Message virtual void Log ( const char * pMsg, ... ) ; - /// Delivers a time/date string + /// Delivers a time/date string const char* Time(void); /// Attaches an Observer to FCConsole void AttachObserver(ConsoleObserver *pcObserver); @@ -548,7 +548,7 @@ public: return level<0?_defaultLogLevel:level; } - /// singleton + /// singleton static ConsoleSingleton &Instance(void); // retrieval of an observer by name @@ -560,7 +560,7 @@ public: void EnableRefresh(bool enable); protected: - // python exports goes here +++++++++++++++++++++++++++++++++++++++++++ + // python exports goes here +++++++++++++++++++++++++++++++++++++++++++ // static python wrapper of the exported functions static PyObject *sPyLog (PyObject *self,PyObject *args); static PyObject *sPyMessage (PyObject *self,PyObject *args); @@ -582,7 +582,7 @@ private: static void Destruct(void); static ConsoleSingleton *_pcSingleton; - // observer processing + // observer processing void NotifyMessage(const char *sMsg); void NotifyWarning(const char *sMsg); void NotifyError (const char *sMsg); @@ -598,9 +598,9 @@ private: }; /** Access to the Console - * This method is used to gain access to the one and only instance of + * This method is used to gain access to the one and only instance of * the ConsoleSingleton class. - */ + */ inline ConsoleSingleton &Console(void){ return ConsoleSingleton::Instance(); } @@ -617,7 +617,7 @@ public: }; -/** LogLevel helper class */ +/** LogLevel helper class */ class BaseExport LogLevel { public: std::string tag; @@ -652,7 +652,7 @@ public: /** The LoggingConsoleObserver class * This class is used by the main modules to write Console messages and logs to a file - */ + */ class BaseExport ConsoleObserverFile : public ConsoleObserver { public: @@ -677,9 +677,9 @@ public: ConsoleObserverStd(); virtual ~ConsoleObserverStd(); virtual void Warning(const char *sWarn); - virtual void Message(const char *sMsg); - virtual void Error (const char *sErr); - virtual void Log (const char *sErr); + virtual void Message(const char *sMsg); + virtual void Error (const char *sErr); + virtual void Log (const char *sErr); const char* Name(void){return "Console";} protected: bool useColorStderr; @@ -725,6 +725,6 @@ private: }; -} // namespace Base +} // namespace Base #endif // BASE_CONSOLE_H