Bug 1495698 - Fix hang when HTML signature references non-existent image.

Tag #1273
This commit is contained in:
Matt A. Tobin 2019-11-10 23:56:17 -05:00 • committed by Roy Tam
commit 3a92a80285
2 changed files with 47 additions and 40 deletions

View file

@ -4350,45 +4350,52 @@ nsMsgCompose::LoadDataFromFile(nsIFile *file, nsString &sigData,
* images loaded into the editor are available on send. * images loaded into the editor are available on send.
*/ */
nsresult nsresult
nsMsgCompose::ReplaceFileURLs(nsAutoString &aData) nsMsgCompose::ReplaceFileURLs(nsString &aData)
{ {
int32_t fPos; int32_t fPos;
int32_t offset = -1; int32_t offset = -1; // We're using RFind(), so offset -1 is from the very right.
// XXX This code is rather incomplete since it looks for "file://" even
// outside tags.
while ((fPos = aData.RFind("file://", true, offset)) != kNotFound) { while ((fPos = aData.RFind("file://", true, offset)) != kNotFound) {
if (fPos != kNotFound && fPos > 0) { bool quoted = false;
char16_t q = aData.CharAt(fPos - 1); char16_t q = 'x'; // initialise to anything to keep compilers happy.
bool quoted = (q == '"' || q == '\''); if (fPos > 0) {
int32_t end = kNotFound; q = aData.CharAt(fPos - 1);
if (quoted) { quoted = (q == '"' || q == '\'');
end = aData.FindChar(q, fPos);
}
else {
int32_t spacePos = aData.FindChar(' ', fPos);
int32_t gtPos = aData.FindChar('>', fPos);
if (gtPos != kNotFound && spacePos != kNotFound) {
end = (spacePos < gtPos) ? spacePos : gtPos;
}
else if (gtPos == kNotFound && spacePos != kNotFound) {
end = spacePos;
}
else if (gtPos != kNotFound && spacePos == kNotFound) {
end = gtPos;
}
}
if (end == kNotFound) {
break;
}
nsString fileURL;
fileURL = Substring(aData, fPos, end - fPos);
nsString dataURL;
nsresult rv = DataURLForFileURL(fileURL, dataURL);
// If this one failed, maybe because the file wasn't found,
// continue to process the next one.
if (NS_SUCCEEDED(rv)) {
aData.Replace(fPos, end - fPos, dataURL);
}
offset = fPos - 1;
} }
int32_t end = kNotFound;
if (quoted) {
end = aData.FindChar(q, fPos);
}
else {
int32_t spacePos = aData.FindChar(' ', fPos);
int32_t gtPos = aData.FindChar('>', fPos);
if (gtPos != kNotFound && spacePos != kNotFound) {
end = (spacePos < gtPos) ? spacePos : gtPos;
}
else if (gtPos == kNotFound && spacePos != kNotFound) {
end = spacePos;
}
else if (gtPos != kNotFound && spacePos == kNotFound) {
end = gtPos;
}
}
if (end == kNotFound) {
break;
}
nsString fileURL;
fileURL = Substring(aData, fPos, end - fPos);
nsString dataURL;
nsresult rv = DataURLForFileURL(fileURL, dataURL);
// If this one failed, maybe because the file wasn't found,
// continue to process the next one.
if (NS_SUCCEEDED(rv)) {
aData.Replace(fPos, end - fPos, dataURL);
}
if (fPos == 0)
break;
offset = fPos - 1;
} }
return NS_OK; return NS_OK;
} }

View file

@ -33,7 +33,7 @@ struct nsMsgMailList;
class nsMsgCompose : public nsIMsgCompose, public nsSupportsWeakReference class nsMsgCompose : public nsIMsgCompose, public nsSupportsWeakReference
{ {
public: public:
nsMsgCompose(); nsMsgCompose();
@ -93,7 +93,7 @@ protected:
nsresult MoveToAboveQuote(void); nsresult MoveToAboveQuote(void);
nsresult MoveToBeginningOfDocument(void); nsresult MoveToBeginningOfDocument(void);
nsresult MoveToEndOfDocument(void); nsresult MoveToEndOfDocument(void);
nsresult ReplaceFileURLs(nsAutoString &sigData); nsresult ReplaceFileURLs(nsString &sigData);
nsresult DataURLForFileURL(const nsAString &aFileURL, nsAString &aDataURL); nsresult DataURLForFileURL(const nsAString &aFileURL, nsAString &aDataURL);
// 3 = To, Cc, Bcc // 3 = To, Cc, Bcc
@ -105,10 +105,10 @@ protected:
*/ */
nsresult LookupAddressBook(RecipientsArray &recipientList); nsresult LookupAddressBook(RecipientsArray &recipientList);
bool IsLastWindow(); bool IsLastWindow();
// Helper function. Parameters are not checked. // Helper function. Parameters are not checked.
bool mConvertStructs; // for TagConvertible bool mConvertStructs; // for TagConvertible
nsCOMPtr<nsIEditor> m_editor; nsCOMPtr<nsIEditor> m_editor;
mozIDOMWindowProxy *m_window; mozIDOMWindowProxy *m_window;
nsCOMPtr<nsIDocShell> mDocShell; nsCOMPtr<nsIDocShell> mDocShell;
@ -147,7 +147,7 @@ protected:
}; };
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
// THIS IS THE CLASS THAT IS THE STREAM Listener OF THE HTML OUPUT // THIS IS THE CLASS THAT IS THE STREAM Listener OF THE HTML OUTPUT
// FROM LIBMIME. THIS IS FOR QUOTING // FROM LIBMIME. THIS IS FOR QUOTING
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
class QuotingOutputStreamListener : public nsIMsgQuotingOutputStreamListener class QuotingOutputStreamListener : public nsIMsgQuotingOutputStreamListener
@ -199,7 +199,7 @@ private:
}; };
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
// This is the listener class for the send operation. We have to create this class // This is the listener class for the send operation. We have to create this class
// to listen for message send completion and eventually notify the caller // to listen for message send completion and eventually notify the caller
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
class nsMsgComposeSendListener : public nsIMsgComposeSendListener, public nsIMsgSendListener, public nsIMsgCopyServiceListener, public nsIWebProgressListener class nsMsgComposeSendListener : public nsIMsgComposeSendListener, public nsIMsgSendListener, public nsIMsgCopyServiceListener, public nsIWebProgressListener
@ -215,10 +215,10 @@ public:
// nsIMsgSendListener interface // nsIMsgSendListener interface
NS_DECL_NSIMSGSENDLISTENER NS_DECL_NSIMSGSENDLISTENER
// nsIMsgCopyServiceListener interface // nsIMsgCopyServiceListener interface
NS_DECL_NSIMSGCOPYSERVICELISTENER NS_DECL_NSIMSGCOPYSERVICELISTENER
// nsIWebProgressListener interface // nsIWebProgressListener interface
NS_DECL_NSIWEBPROGRESSLISTENER NS_DECL_NSIWEBPROGRESSLISTENER