From cb3e487353cf743aaa0076ed2a75271b7e5eb7fd Mon Sep 17 00:00:00 2001 From: "sfraser%netscape.com" Date: Thu, 8 Mar 2001 00:59:54 +0000 Subject: [PATCH] Fix for bug 67466 -- don't crash when opening lots of files on startup. r=pinkerton, sr=beard --- xpfe/appshell/src/nsCommandLineServiceMac.cpp | 64 +++++++------------ xpfe/appshell/src/nsCommandLineServiceMac.h | 9 +-- .../startup/src/nsCommandLineServiceMac.cpp | 64 +++++++------------ .../startup/src/nsCommandLineServiceMac.h | 9 +-- 4 files changed, 58 insertions(+), 88 deletions(-) diff --git a/xpfe/appshell/src/nsCommandLineServiceMac.cpp b/xpfe/appshell/src/nsCommandLineServiceMac.cpp index 2e4c85d0648..3ccc5d9f231 100644 --- a/xpfe/appshell/src/nsCommandLineServiceMac.cpp +++ b/xpfe/appshell/src/nsCommandLineServiceMac.cpp @@ -59,7 +59,7 @@ nsMacCommandLine nsMacCommandLine::sMacCommandLine; //---------------------------------------------------------------------------------------- nsMacCommandLine::nsMacCommandLine() -: mArgBuffer(NULL) +: mArgsBuffer(NULL) , mArgs(NULL) , mStartedUp(PR_FALSE) //---------------------------------------------------------------------------------------- @@ -72,6 +72,8 @@ nsMacCommandLine::~nsMacCommandLine() //---------------------------------------------------------------------------------------- { ShutdownAEHandlerClasses(); + nsMemory::Free(mArgsBuffer); + mArgsBuffer = NULL; } @@ -85,6 +87,9 @@ nsresult nsMacCommandLine::Initialize(int& argc, char**& argv) argc = 0; argv = mArgs; + // init the args buffer with the program name + mTempArgsString.Assign("mozilla"); + // Set up AppleEvent handling. OSErr err = CreateAEHandlerClasses(false); if (err != noErr) return NS_ERROR_FAILURE; @@ -105,25 +110,27 @@ nsresult nsMacCommandLine::Initialize(int& argc, char**& argv) { ::WaitNextEvent(highLevelEventMask, &anEvent, 0, nsnull); if (anEvent.what == kHighLevelEvent) + { + // here we process startup odoc/pdoc events, which can + // add items to the command line. err = ::AEProcessAppleEvent(&anEvent); + } } - // we've started up now mStartedUp = PR_TRUE; + + // Care! We have to ensure that the addresses we pass out in + // argv continue to point to valid memory. Because we can't guarantee + // anything about the way that nsCString works, we make a copy + // of the buffer, which is never freed until the command line handler + // goes way (and, since it's static, that is at library unload time). + + mArgsBuffer = mTempArgsString.ToNewCString(); + mTempArgsString.Truncate(); // it's job is done - if (!mArgBuffer) // no arguments from anywhere - return NS_OK; - - // Release some unneeded memory - char* oldBuffer = mArgBuffer; - mArgBuffer = new char[PL_strlen(mArgBuffer) + 1]; - PL_strcpy(mArgBuffer, oldBuffer); - delete [] oldBuffer; - // Parse the buffer. - int rowNumber = 0; - char* strtokFirstParam = mArgBuffer; + char* strtokFirstParam = mArgsBuffer; while (argc < kMaxTokens) { // Get the next token. Initialize strtok by passing the string the @@ -147,37 +154,17 @@ nsresult nsMacCommandLine::Initialize(int& argc, char**& argv) delete [] oldArgs; argv = mArgs; } - + return NS_OK; } - -//---------------------------------------------------------------------------------------- -PRBool nsMacCommandLine::EnsureCommandLine() -//---------------------------------------------------------------------------------------- -{ - if (mArgBuffer) - return PR_TRUE; - - mArgBuffer = new char[kMaxBufferSize]; - if (!mArgBuffer) - return PR_FALSE; - - PL_strcpy(mArgBuffer, "mozilla"); // argv[0] - return PR_TRUE; -} - - //---------------------------------------------------------------------------------------- nsresult nsMacCommandLine::AddToCommandLine(const char* inArgText) //---------------------------------------------------------------------------------------- { - if (!EnsureCommandLine()) - return NS_ERROR_OUT_OF_MEMORY; - if (*inArgText != ' ') - PL_strcat(mArgBuffer, " "); - PL_strcat(mArgBuffer, inArgText); + mTempArgsString.Append(" "); + mTempArgsString.Append(inArgText); return NS_OK; } @@ -186,13 +173,10 @@ nsresult nsMacCommandLine::AddToCommandLine(const char* inArgText) nsresult nsMacCommandLine::AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec) //---------------------------------------------------------------------------------------- { - if (!EnsureCommandLine()) - return NS_ERROR_OUT_OF_MEMORY; - // Convert the filespec to a URL nsFileSpec nsspec(inFileSpec); nsFileURL fileAsURL(nsspec); - PL_strcat(mArgBuffer, " "); + mTempArgsString.Append(" "); AddToCommandLine(inOptionString); AddToCommandLine(fileAsURL.GetAsString()); return NS_OK; diff --git a/xpfe/appshell/src/nsCommandLineServiceMac.h b/xpfe/appshell/src/nsCommandLineServiceMac.h index 098852a48d7..ff83d0b7d04 100644 --- a/xpfe/appshell/src/nsCommandLineServiceMac.h +++ b/xpfe/appshell/src/nsCommandLineServiceMac.h @@ -29,6 +29,7 @@ #include "nscore.h" #include "nsError.h" +#include "nsString.h" #include "nsAEDefs.h" @@ -41,7 +42,6 @@ public: enum { - kMaxBufferSize = 512, kMaxTokens = 20 }; @@ -50,7 +50,6 @@ public: nsresult Initialize(int& argc, char**& argv); - PRBool EnsureCommandLine(); nsresult AddToCommandLine(const char* inArgText); nsresult AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec); nsresult AddToEnvironmentVars(const char* inArgText); @@ -66,8 +65,10 @@ protected: nsresult OpenWindow(const char *chrome, const PRUnichar *url); - char* mArgBuffer; // the command line itself - char** mArgs; // array of pointers into argBuffer + nsCString mTempArgsString; // temp storage for args as we accumulate them + char* mArgsBuffer; // final, immutable container for args + + char** mArgs; // array of pointers into argBuffer PRBool mStartedUp; diff --git a/xpfe/components/startup/src/nsCommandLineServiceMac.cpp b/xpfe/components/startup/src/nsCommandLineServiceMac.cpp index 2e4c85d0648..3ccc5d9f231 100644 --- a/xpfe/components/startup/src/nsCommandLineServiceMac.cpp +++ b/xpfe/components/startup/src/nsCommandLineServiceMac.cpp @@ -59,7 +59,7 @@ nsMacCommandLine nsMacCommandLine::sMacCommandLine; //---------------------------------------------------------------------------------------- nsMacCommandLine::nsMacCommandLine() -: mArgBuffer(NULL) +: mArgsBuffer(NULL) , mArgs(NULL) , mStartedUp(PR_FALSE) //---------------------------------------------------------------------------------------- @@ -72,6 +72,8 @@ nsMacCommandLine::~nsMacCommandLine() //---------------------------------------------------------------------------------------- { ShutdownAEHandlerClasses(); + nsMemory::Free(mArgsBuffer); + mArgsBuffer = NULL; } @@ -85,6 +87,9 @@ nsresult nsMacCommandLine::Initialize(int& argc, char**& argv) argc = 0; argv = mArgs; + // init the args buffer with the program name + mTempArgsString.Assign("mozilla"); + // Set up AppleEvent handling. OSErr err = CreateAEHandlerClasses(false); if (err != noErr) return NS_ERROR_FAILURE; @@ -105,25 +110,27 @@ nsresult nsMacCommandLine::Initialize(int& argc, char**& argv) { ::WaitNextEvent(highLevelEventMask, &anEvent, 0, nsnull); if (anEvent.what == kHighLevelEvent) + { + // here we process startup odoc/pdoc events, which can + // add items to the command line. err = ::AEProcessAppleEvent(&anEvent); + } } - // we've started up now mStartedUp = PR_TRUE; + + // Care! We have to ensure that the addresses we pass out in + // argv continue to point to valid memory. Because we can't guarantee + // anything about the way that nsCString works, we make a copy + // of the buffer, which is never freed until the command line handler + // goes way (and, since it's static, that is at library unload time). + + mArgsBuffer = mTempArgsString.ToNewCString(); + mTempArgsString.Truncate(); // it's job is done - if (!mArgBuffer) // no arguments from anywhere - return NS_OK; - - // Release some unneeded memory - char* oldBuffer = mArgBuffer; - mArgBuffer = new char[PL_strlen(mArgBuffer) + 1]; - PL_strcpy(mArgBuffer, oldBuffer); - delete [] oldBuffer; - // Parse the buffer. - int rowNumber = 0; - char* strtokFirstParam = mArgBuffer; + char* strtokFirstParam = mArgsBuffer; while (argc < kMaxTokens) { // Get the next token. Initialize strtok by passing the string the @@ -147,37 +154,17 @@ nsresult nsMacCommandLine::Initialize(int& argc, char**& argv) delete [] oldArgs; argv = mArgs; } - + return NS_OK; } - -//---------------------------------------------------------------------------------------- -PRBool nsMacCommandLine::EnsureCommandLine() -//---------------------------------------------------------------------------------------- -{ - if (mArgBuffer) - return PR_TRUE; - - mArgBuffer = new char[kMaxBufferSize]; - if (!mArgBuffer) - return PR_FALSE; - - PL_strcpy(mArgBuffer, "mozilla"); // argv[0] - return PR_TRUE; -} - - //---------------------------------------------------------------------------------------- nsresult nsMacCommandLine::AddToCommandLine(const char* inArgText) //---------------------------------------------------------------------------------------- { - if (!EnsureCommandLine()) - return NS_ERROR_OUT_OF_MEMORY; - if (*inArgText != ' ') - PL_strcat(mArgBuffer, " "); - PL_strcat(mArgBuffer, inArgText); + mTempArgsString.Append(" "); + mTempArgsString.Append(inArgText); return NS_OK; } @@ -186,13 +173,10 @@ nsresult nsMacCommandLine::AddToCommandLine(const char* inArgText) nsresult nsMacCommandLine::AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec) //---------------------------------------------------------------------------------------- { - if (!EnsureCommandLine()) - return NS_ERROR_OUT_OF_MEMORY; - // Convert the filespec to a URL nsFileSpec nsspec(inFileSpec); nsFileURL fileAsURL(nsspec); - PL_strcat(mArgBuffer, " "); + mTempArgsString.Append(" "); AddToCommandLine(inOptionString); AddToCommandLine(fileAsURL.GetAsString()); return NS_OK; diff --git a/xpfe/components/startup/src/nsCommandLineServiceMac.h b/xpfe/components/startup/src/nsCommandLineServiceMac.h index 098852a48d7..ff83d0b7d04 100644 --- a/xpfe/components/startup/src/nsCommandLineServiceMac.h +++ b/xpfe/components/startup/src/nsCommandLineServiceMac.h @@ -29,6 +29,7 @@ #include "nscore.h" #include "nsError.h" +#include "nsString.h" #include "nsAEDefs.h" @@ -41,7 +42,6 @@ public: enum { - kMaxBufferSize = 512, kMaxTokens = 20 }; @@ -50,7 +50,6 @@ public: nsresult Initialize(int& argc, char**& argv); - PRBool EnsureCommandLine(); nsresult AddToCommandLine(const char* inArgText); nsresult AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec); nsresult AddToEnvironmentVars(const char* inArgText); @@ -66,8 +65,10 @@ protected: nsresult OpenWindow(const char *chrome, const PRUnichar *url); - char* mArgBuffer; // the command line itself - char** mArgs; // array of pointers into argBuffer + nsCString mTempArgsString; // temp storage for args as we accumulate them + char* mArgsBuffer; // final, immutable container for args + + char** mArgs; // array of pointers into argBuffer PRBool mStartedUp;