-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I sent this message to jon today. Afterwards i remembered that he is quite busy these days and i decided to let the list have a look at it, too ;)
- ---------------- [snip] - ---------------- Hi Jon, we have a general problem with the design of licq's config files :-( Please read bug report 424504 on SF. (http://sourceforge.net/tracker/index.php?func=detail&aid=424504&group_id=254&atid=100254). The problem is, that leading and trailing whitespaces are automatically removed from the configuration-value/data after the "=" in config files. In most cases this is good behaviour, but in some special cases removing leading or trailing spaces is a bad idea (for example if your password begins or ends with a space character). I have a patch for Bug 424504, but it's no final solution at all and the patch only workarounds the problem with _trailing_ spaces in password. if the password _begins_ with space, the problem still exists :( I did not work on this any further because this way of fixing concentrates on the bug-symptoms, but not on cause of this bug. The main problem is, that currently the first and last SPACE is used as string termination criteria (which could in some cases be part of the configuration data/value!!) What about taking first and last quotation mark as termination character? I know that this would lead into breaking already existing configuration files :( Do you have any idea? I'd like to avoid a change in configuration file design, but i have no clue how we could fix this bug otherwise :( Ok, of course i could implement special handling for the owner password, but i'd like to avoid that. IMO the CIniFile object should be as generalized as it can be, there should be no special cases at all. I attach my patch that you can see the exact problem. I summarize what IMO could be a potential solution: ____________________________________________________ 1. Change Configuration file design to use a specified string termination character (cleanest solution, but breaks older config files) 2. Implement special handling for the owners password case (ugly *brrr*) 3. Make CIniFile only remove first space after "=" and treat the string between next and last space as configuration value (may break other things that rely on having no leading or trailing spaces in config-value/data -> needs further investigation). 4. Leave everything as is and forbit leading/trailing spaces in owner password (breaks ICQ's password guidelines) Do you have a another/better idea? Bye, Thomas - -- If only one could get that wonderful feeling of accomplishment without having to accomplish anything. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQE9q/RR+83LmoKU5MARAkzhAJ9JW2Wxz++2pttPVrMWfM3obsvJyQCghGuk PmC/spX8+wpelMS+CfCA9wg= =7ixs -----END PGP SIGNATURE-----
Index: licq/src/file.cpp =================================================================== RCS file: /cvsroot/licq/licq/src/file.cpp,v retrieving revision 1.7 diff -u -3 -p -r1.7 file.cpp --- licq/src/file.cpp 14 Sep 2002 21:41:42 -0000 1.7 +++ licq/src/file.cpp 15 Oct 2002 09:36:06 -0000 @@ -25,7 +25,7 @@ extern int errno; /*-----Trim-------------------------------------------------------------------- * Removes leading and trailing spaces from a string *---------------------------------------------------------------------------*/ -void Trim(char *_sz) +void Trim(char *_sz, bool bTrimTrailing = true) { if (_sz == NULL) { @@ -46,7 +46,10 @@ void Trim(char *_sz) } // e is now on the last character - e--; while(e != b && isspace(*e)) e--; e++; + if (bTrimTrailing) + { + e--; while(e != b && isspace(*e)) e--; e++; + } // now b is the beginning and e on the supposed 0 byte // of the new string, lets copy if necessary @@ -481,7 +484,7 @@ char *CIniFile::GetKeyFromLine(char *_sz * Returns NULL if the given line is NULL or there is no '=' on the line. *---------------------------------------------------------------------------*/ char *CIniFile::GetDataFromLine(char *_szBuffer, const char *_szLine, - bool bTrim) + bool bTrim, bool bTrimTrailing) { //static char s_szData[MAX_LINE_LEN]; char *szPostEquals; @@ -508,7 +511,7 @@ char *CIniFile::GetDataFromLine(char *_s strncpy(szData, szPostEquals + 1, MAX_LINE_LEN); szData[MAX_LINE_LEN - 1] = '\0'; - if (bTrim) Trim(szData); + if (bTrim) Trim(szData, bTrimTrailing); AddNewLines(_szBuffer, szData); } return (_szBuffer); @@ -585,7 +588,7 @@ bool CIniFile::SetSection(const char *_s * Finds a key and sets the data. Returns false if the key does not exist. *---------------------------------------------------------------------------*/ bool CIniFile::ReadStr(const char *szKey, char *szData, - const char *szDefault, bool bTrim) + const char *szDefault, bool bTrim, bool bTrimTrailing) { char *sz, *szLine, szLineBuffer[MAX_LINE_LEN], szKeyBuffer[MAX_KEYxNAME_LEN]; @@ -604,7 +607,7 @@ bool CIniFile::ReadStr(const char *szKey } while (strcmp(sz, szKey) != 0); - if ((sz = GetDataFromLine(szData, szLine, bTrim)) == NULL) + if ((sz = GetDataFromLine(szData, szLine, bTrim, bTrimTrailing)) == NULL) { if (szDefault != NULL) strcpy(szData, szDefault); return (false); Index: licq/src/user.cpp =================================================================== RCS file: /cvsroot/licq/licq/src/user.cpp,v retrieving revision 1.57 diff -u -3 -p -r1.57 user.cpp --- licq/src/user.cpp 29 Sep 2002 23:43:54 -0000 1.57 +++ licq/src/user.cpp 15 Oct 2002 09:36:06 -0000 @@ -2513,7 +2513,7 @@ ICQOwner::ICQOwner() m_fConf.SetFileName(filename); LoadInfo(); m_fConf.ReadNum("Uin", m_nUin, 0); - m_fConf.ReadStr("Password", szTemp, ""); + m_fConf.ReadStr("Password", szTemp, "", true, false); SetPassword(szTemp); if (szTemp[0] == '\0' && m_nUin != 0) { Index: licq/include/licq_file.h =================================================================== RCS file: /cvsroot/licq/licq/include/licq_file.h,v retrieving revision 1.3 diff -u -3 -p -r1.3 licq_file.h --- licq/include/licq_file.h 15 Jul 2002 04:46:12 -0000 1.3 +++ licq/include/licq_file.h 15 Oct 2002 09:36:06 -0000 @@ -45,7 +45,7 @@ public: bool SetSection(const char *_szSectionName); bool CreateSection(const char *_szSectionName); - bool ReadStr(const char *_szKey, char *_szData, const char *_szDefault = NULL, bool bTrim = true); + bool ReadStr(const char *_szKey, char *_szData, const char *_szDefault = NULL, bool bTrim = true, bool bTrimTrailing = true); bool ReadNum(const char *_szKey, unsigned long &data, const unsigned long _nDefault = 0); bool ReadNum(const char *_szKey, unsigned short &data, const unsigned short _nDefault = 0); bool ReadNum(const char *_szKey, signed short &data, const signed short _nDefault = 0); @@ -82,7 +82,7 @@ protected: char *GetSectionFromLine(char *_szBuffer, const char *_szLine); char *GetKeyFromLine(char *_szBuffer, const char *_szLine); char *GetDataFromLine(char *_szBuffer, const char *_szLine, - bool bTrim = true); + bool bTrim = true, bool bTrimTrailin = true); void Warn(int nError, const char *_sz = NULL); void InsertStr(const char *_szNewStr, int _nCutStart, int _nCutEnd);