Bug 1919290 - Type checking for an initial set of closure parameters in C MIME code. r=mkmelin
Differential Revision: https://phabricator.services.mozilla.com/D222475 --HG-- extra : rebase_source : 744f1bf4c96356538f48996f27decea1d47b85a1
This commit is contained in:
Родитель
84fc0b8087
Коммит
30ce1a27b4
|
@ -60,13 +60,13 @@ extern "C" MimeObjectClass* MIME_PgpMimeCreateContentTypeHandlerClass(
|
|||
return objClass;
|
||||
}
|
||||
|
||||
static void* MimePgpe_init(MimeObject*,
|
||||
int (*output_fn)(const char*, int32_t, void*),
|
||||
void*);
|
||||
static int MimePgpe_write(const char*, int32_t, void*);
|
||||
static int MimePgpe_eof(void*, bool);
|
||||
static char* MimePgpe_generate(void*);
|
||||
static void MimePgpe_free(void*);
|
||||
static MimeClosure MimePgpe_init(MimeObject*,
|
||||
int (*output_fn)(const char*, int32_t, void*),
|
||||
void*);
|
||||
static int MimePgpe_write(const char*, int32_t, MimeClosure);
|
||||
static int MimePgpe_eof(MimeClosure, bool);
|
||||
static char* MimePgpe_generate(MimeClosure);
|
||||
static void MimePgpe_free(MimeClosure);
|
||||
|
||||
/* Returns a string describing the location of the part (like "2.5.3").
|
||||
This is not a full URL, just a part-number.
|
||||
|
@ -128,14 +128,15 @@ class MimePgpeData : public nsISupports {
|
|||
|
||||
NS_IMPL_ISUPPORTS0(MimePgpeData)
|
||||
|
||||
static void* MimePgpe_init(MimeObject* obj,
|
||||
int (*output_fn)(const char* buf, int32_t buf_size,
|
||||
void* output_closure),
|
||||
void* output_closure) {
|
||||
if (!(obj && obj->options && output_fn)) return nullptr;
|
||||
static MimeClosure MimePgpe_init(MimeObject* obj,
|
||||
int (*output_fn)(const char* buf,
|
||||
int32_t buf_size,
|
||||
void* output_closure),
|
||||
void* output_closure) {
|
||||
if (!(obj && obj->options && output_fn)) return MimeClosure::zero();
|
||||
|
||||
MimePgpeData* data = new MimePgpeData();
|
||||
NS_ENSURE_TRUE(data, nullptr);
|
||||
NS_ENSURE_TRUE(data, MimeClosure::zero());
|
||||
|
||||
data->self = obj;
|
||||
data->output_fn = output_fn;
|
||||
|
@ -145,7 +146,7 @@ static void* MimePgpe_init(MimeObject* obj,
|
|||
// Create proxy object.
|
||||
nsresult rv;
|
||||
data->mimeDecrypt = do_CreateInstance(NS_PGPMIMEPROXY_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return data;
|
||||
if (NS_FAILED(rv)) return MimeClosure(MimeClosure::isMimePgpeData, data);
|
||||
|
||||
char* ct = MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE, false, false);
|
||||
|
||||
|
@ -154,12 +155,12 @@ static void* MimePgpe_init(MimeObject* obj,
|
|||
|
||||
PR_Free(ct);
|
||||
|
||||
if (NS_FAILED(rv)) return nullptr;
|
||||
if (NS_FAILED(rv)) return MimeClosure::zero();
|
||||
|
||||
nsCString mimePart = determineMimePart(obj);
|
||||
|
||||
rv = data->mimeDecrypt->SetMimePart(mimePart);
|
||||
if (NS_FAILED(rv)) return nullptr;
|
||||
if (NS_FAILED(rv)) return MimeClosure::zero();
|
||||
|
||||
if (mimePart.EqualsLiteral("1.1") && obj->parent &&
|
||||
obj->parent->content_type &&
|
||||
|
@ -176,14 +177,22 @@ static void* MimePgpe_init(MimeObject* obj,
|
|||
data->mimeDecrypt->SetAllowNestedDecrypt(true);
|
||||
}
|
||||
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(data->self->options->stream_closure);
|
||||
nsIChannel* channel = msd->channel;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIMailChannel> mailChannel;
|
||||
if (channel) {
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
mailChannel = do_QueryInterface(channel);
|
||||
|
||||
PR_ASSERT(data->self->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData ||
|
||||
data->self->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeDraftData);
|
||||
if (data->self->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData) {
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(data->self->options->stream_closure.mClosure);
|
||||
nsIChannel* channel = msd->channel;
|
||||
if (channel) {
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
mailChannel = do_QueryInterface(channel);
|
||||
}
|
||||
}
|
||||
|
||||
if (!uri && obj && obj->options && obj->options->url) {
|
||||
|
@ -196,26 +205,42 @@ static void* MimePgpe_init(MimeObject* obj,
|
|||
// Initialise proxy object with MIME's output function, object and URI.
|
||||
if (NS_FAILED(data->mimeDecrypt->SetMimeCallback(output_fn, output_closure,
|
||||
uri, mailChannel)))
|
||||
return nullptr;
|
||||
return MimeClosure::zero();
|
||||
|
||||
return data;
|
||||
return MimeClosure(MimeClosure::isMimePgpeData, data);
|
||||
}
|
||||
|
||||
static int MimePgpe_write(const char* buf, int32_t buf_size,
|
||||
void* output_closure) {
|
||||
MimePgpeData* data = (MimePgpeData*)output_closure;
|
||||
MimeClosure output_closure) {
|
||||
if (!output_closure) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!data || !data->output_fn) return -1;
|
||||
PR_ASSERT(output_closure.mType == MimeClosure::isMimePgpeData);
|
||||
if (output_closure.mType != MimeClosure::isMimePgpeData) {
|
||||
return -1;
|
||||
}
|
||||
MimePgpeData* data = (MimePgpeData*)output_closure.mClosure;
|
||||
|
||||
if (!data->output_fn) return -1;
|
||||
|
||||
if (!data->mimeDecrypt) return 0;
|
||||
|
||||
return (NS_SUCCEEDED(data->mimeDecrypt->Write(buf, buf_size)) ? 0 : -1);
|
||||
}
|
||||
|
||||
static int MimePgpe_eof(void* output_closure, bool abort_p) {
|
||||
MimePgpeData* data = (MimePgpeData*)output_closure;
|
||||
static int MimePgpe_eof(MimeClosure output_closure, bool abort_p) {
|
||||
if (!output_closure) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!data || !data->output_fn) return -1;
|
||||
PR_ASSERT(output_closure.mType == MimeClosure::isMimePgpeData);
|
||||
if (output_closure.mType != MimeClosure::isMimePgpeData) {
|
||||
return -1;
|
||||
}
|
||||
MimePgpeData* data = (MimePgpeData*)output_closure.mClosure;
|
||||
|
||||
if (!data->output_fn) return -1;
|
||||
|
||||
if (NS_FAILED(data->mimeDecrypt->Finish())) return -1;
|
||||
|
||||
|
@ -224,7 +249,7 @@ static int MimePgpe_eof(void* output_closure, bool abort_p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char* MimePgpe_generate(void* output_closure) {
|
||||
static char* MimePgpe_generate(MimeClosure output_closure) {
|
||||
const char htmlMsg[] = "<html><body><b>GEN MSG<b></body></html>";
|
||||
char* msg = (char*)PR_MALLOC(strlen(htmlMsg) + 1);
|
||||
if (msg) PL_strcpy(msg, htmlMsg);
|
||||
|
@ -232,8 +257,12 @@ static char* MimePgpe_generate(void* output_closure) {
|
|||
return msg;
|
||||
}
|
||||
|
||||
static void MimePgpe_free(void* output_closure) {
|
||||
MimePgpeData* data = (MimePgpeData*)output_closure;
|
||||
static void MimePgpe_free(MimeClosure output_closure) {
|
||||
PR_ASSERT(output_closure.mType == MimeClosure::isMimePgpeData);
|
||||
if (output_closure.mType != MimeClosure::isMimePgpeData) {
|
||||
return;
|
||||
}
|
||||
MimePgpeData* data = (MimePgpeData*)output_closure.mClosure;
|
||||
if (data->mimeDecrypt) {
|
||||
data->mimeDecrypt->RemoveMimeCallback();
|
||||
data->mimeDecrypt = nullptr;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _MIME_CLOSURE_H_
|
||||
#define _MIME_CLOSURE_H_
|
||||
|
||||
class MimeClosure {
|
||||
public:
|
||||
enum ClosureType {
|
||||
isUndefined = 0,
|
||||
isMimeObject = 1,
|
||||
isMimeStreamData,
|
||||
isMimeCMSData,
|
||||
isMimeMultCMSData,
|
||||
isMimePgpeData,
|
||||
isMimeDraftData,
|
||||
isMimeMultipartRelated,
|
||||
};
|
||||
|
||||
MimeClosure() : mType(isUndefined), mClosure(nullptr) {}
|
||||
MimeClosure(ClosureType t, void* c) : mType(t), mClosure(c) {}
|
||||
|
||||
static MimeClosure zero() { return MimeClosure(); }
|
||||
|
||||
MimeClosure& operator=(const MimeClosure& other) {
|
||||
if (this == &other) return *this;
|
||||
|
||||
mType = other.mType;
|
||||
mClosure = other.mClosure;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// explicit: the bool value cannot get implicitly converted to
|
||||
// integer or pointer.
|
||||
explicit operator bool() const { return mClosure != nullptr; }
|
||||
|
||||
ClosureType mType;
|
||||
void* mClosure;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -41,47 +41,6 @@ extern "C" int mime_GrowBuffer(uint32_t desired_size, uint32_t element_size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* The opposite of mime_LineBuffer(): takes small buffers and packs them
|
||||
up into bigger buffers before passing them along.
|
||||
|
||||
Pass in a desired_buffer_size 0 to tell it to flush (for example, in
|
||||
in the very last call to this function.)
|
||||
*/
|
||||
extern "C" int mime_ReBuffer(const char* net_buffer, int32_t net_buffer_size,
|
||||
uint32_t desired_buffer_size, char** bufferP,
|
||||
int32_t* buffer_sizeP, uint32_t* buffer_fpP,
|
||||
int32_t (*per_buffer_fn)(char* buffer,
|
||||
uint32_t buffer_size,
|
||||
void* closure),
|
||||
void* closure) {
|
||||
int status = 0;
|
||||
|
||||
if (desired_buffer_size >= (uint32_t)(*buffer_sizeP)) {
|
||||
status = mime_GrowBuffer(desired_buffer_size, sizeof(char), 1024, bufferP,
|
||||
buffer_sizeP);
|
||||
if (status < 0) return status;
|
||||
}
|
||||
|
||||
do {
|
||||
int32_t size = *buffer_sizeP - *buffer_fpP;
|
||||
if (size > net_buffer_size) size = net_buffer_size;
|
||||
if (size > 0) {
|
||||
memcpy((*bufferP) + (*buffer_fpP), net_buffer, size);
|
||||
(*buffer_fpP) += size;
|
||||
net_buffer += size;
|
||||
net_buffer_size -= size;
|
||||
}
|
||||
|
||||
if (*buffer_fpP > 0 && *buffer_fpP >= desired_buffer_size) {
|
||||
status = (*per_buffer_fn)((*bufferP), (*buffer_fpP), closure);
|
||||
*buffer_fpP = 0;
|
||||
if (status < 0) return status;
|
||||
}
|
||||
} while (net_buffer_size > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int convert_and_send_buffer(char* buf, int length,
|
||||
bool convert_newlines_p,
|
||||
int32_t (*per_line_fn)(const char* line,
|
||||
|
|
|
@ -28,12 +28,4 @@ extern "C" int mime_LineBuffer(const char* net_buffer, int32_t net_buffer_size,
|
|||
MimeObject* closure),
|
||||
MimeObject* closure);
|
||||
|
||||
extern "C" int mime_ReBuffer(const char* net_buffer, int32_t net_buffer_size,
|
||||
uint32_t desired_buffer_size, char** bufferP,
|
||||
uint32_t* buffer_sizeP, uint32_t* buffer_fpP,
|
||||
int32_t (*per_buffer_fn)(char* buffer,
|
||||
uint32_t buffer_size,
|
||||
void* closure),
|
||||
void* closure);
|
||||
|
||||
#endif /* _MIMEBUF_H_ */
|
||||
|
|
|
@ -33,12 +33,13 @@ using namespace mozilla::mailnews;
|
|||
MimeDefClass(MimeEncryptedCMS, MimeEncryptedCMSClass, mimeEncryptedCMSClass,
|
||||
&MIME_SUPERCLASS);
|
||||
|
||||
static void* MimeCMS_init(MimeObject*,
|
||||
int (*output_fn)(const char*, int32_t, void*), void*);
|
||||
static int MimeCMS_write(const char*, int32_t, void*);
|
||||
static int MimeCMS_eof(void*, bool);
|
||||
static char* MimeCMS_generate(void*);
|
||||
static void MimeCMS_free(void*);
|
||||
static MimeClosure MimeCMS_init(MimeObject*,
|
||||
int (*output_fn)(const char*, int32_t, void*),
|
||||
void*);
|
||||
static int MimeCMS_write(const char*, int32_t, MimeClosure);
|
||||
static int MimeCMS_eof(MimeClosure, bool);
|
||||
static char* MimeCMS_generate(MimeClosure);
|
||||
static void MimeCMS_free(MimeClosure);
|
||||
|
||||
extern int SEC_ERROR_CERT_ADDR_MISMATCH;
|
||||
|
||||
|
@ -141,8 +142,15 @@ bool MimeEncryptedCMS_encrypted_p(MimeObject* obj) {
|
|||
if (!obj) return false;
|
||||
if (mime_typep(obj, (MimeObjectClass*)&mimeEncryptedCMSClass)) {
|
||||
MimeEncrypted* enc = (MimeEncrypted*)obj;
|
||||
MimeCMSdata* data = (MimeCMSdata*)enc->crypto_closure;
|
||||
if (!data || !data->content_info) return false;
|
||||
|
||||
if (!enc->crypto_closure) return false;
|
||||
|
||||
PR_ASSERT(enc->crypto_closure.mType == MimeClosure::isMimeCMSData);
|
||||
if (enc->crypto_closure.mType != MimeClosure::isMimeCMSData) {
|
||||
return false;
|
||||
}
|
||||
MimeCMSdata* data = (MimeCMSdata*)enc->crypto_closure.mClosure;
|
||||
if (!data->content_info) return false;
|
||||
data->content_info->GetContentIsEncrypted(&encrypted);
|
||||
return encrypted;
|
||||
}
|
||||
|
@ -161,8 +169,15 @@ bool MimeEncOrMP_CMS_signed_p(MimeObject* obj) {
|
|||
}
|
||||
if (mime_typep(obj, (MimeObjectClass*)&mimeEncryptedCMSClass)) {
|
||||
MimeEncrypted* enc = (MimeEncrypted*)obj;
|
||||
MimeCMSdata* data = (MimeCMSdata*)enc->crypto_closure;
|
||||
if (!data || !data->content_info) return false;
|
||||
|
||||
if (!enc->crypto_closure) return false;
|
||||
|
||||
PR_ASSERT(enc->crypto_closure.mType == MimeClosure::isMimeCMSData);
|
||||
if (enc->crypto_closure.mType != MimeClosure::isMimeCMSData) {
|
||||
return false;
|
||||
}
|
||||
MimeCMSdata* data = (MimeCMSdata*)enc->crypto_closure.mClosure;
|
||||
if (!data->content_info) return false;
|
||||
data->content_info->GetContentIsSigned(&is_signed);
|
||||
return is_signed;
|
||||
}
|
||||
|
@ -501,17 +516,19 @@ int MIMEGetRelativeCryptoNestLevel(MimeObject* obj) {
|
|||
return aCryptoPartNestLevel - aTopMessageNestLevel;
|
||||
}
|
||||
|
||||
static void* MimeCMS_init(MimeObject* obj,
|
||||
int (*output_fn)(const char* buf, int32_t buf_size,
|
||||
void* output_closure),
|
||||
void* output_closure) {
|
||||
static MimeClosure MimeCMS_init(MimeObject* obj,
|
||||
int (*output_fn)(const char* buf,
|
||||
int32_t buf_size,
|
||||
void* output_closure),
|
||||
void* output_closure) {
|
||||
MimeCMSdata* data;
|
||||
nsresult rv;
|
||||
|
||||
if (!(obj && obj->options && output_fn)) return 0;
|
||||
if (!(obj && obj->options && output_fn))
|
||||
return MimeClosure(MimeClosure::isUndefined, 0);
|
||||
|
||||
data = new MimeCMSdata;
|
||||
if (!data) return 0;
|
||||
if (!data) return MimeClosure(MimeClosure::isUndefined, 0);
|
||||
|
||||
data->self = obj;
|
||||
data->output_fn = output_fn;
|
||||
|
@ -537,58 +554,72 @@ static void* MimeCMS_init(MimeObject* obj,
|
|||
data->decoder_context = do_CreateInstance(NS_CMSDECODER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete data;
|
||||
return 0;
|
||||
return MimeClosure(MimeClosure::isUndefined, 0);
|
||||
}
|
||||
|
||||
rv = data->decoder_context->Start(MimeCMS_content_callback, data);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete data;
|
||||
return 0;
|
||||
return MimeClosure(MimeClosure::isUndefined, 0);
|
||||
}
|
||||
}
|
||||
|
||||
data->any_parent_is_encrypted_p = MimeAnyParentCMSEncrypted(obj);
|
||||
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(data->self->options->stream_closure);
|
||||
if (msd) {
|
||||
nsIChannel* channel = msd->channel; // note the lack of ref counting...
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
rv = uri->GetSpec(data->url);
|
||||
if (data->self->options->stream_closure) {
|
||||
PR_ASSERT(data->self->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData ||
|
||||
data->self->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeDraftData);
|
||||
if (data->self->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData) {
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(data->self->options->stream_closure.mClosure);
|
||||
nsIChannel* channel = msd->channel; // note the lack of ref counting...
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
channel->GetURI(getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
rv = uri->GetSpec(data->url);
|
||||
|
||||
// We only want to update the UI if the current mime transaction
|
||||
// is intended for display.
|
||||
// If the current transaction is intended for background processing,
|
||||
// we can learn that by looking at the additional header=filter
|
||||
// string contained in the URI.
|
||||
//
|
||||
// If we find something, we do not set smimeSink,
|
||||
// which will prevent us from giving UI feedback.
|
||||
//
|
||||
// If we do not find header=filter, we assume the result of the
|
||||
// processing will be shown in the UI.
|
||||
// We only want to update the UI if the current mime transaction
|
||||
// is intended for display.
|
||||
// If the current transaction is intended for background processing,
|
||||
// we can learn that by looking at the additional header=filter
|
||||
// string contained in the URI.
|
||||
//
|
||||
// If we find something, we do not set smimeSink,
|
||||
// which will prevent us from giving UI feedback.
|
||||
//
|
||||
// If we do not find header=filter, we assume the result of the
|
||||
// processing will be shown in the UI.
|
||||
|
||||
if (!strstr(data->url.get(), "?header=filter") &&
|
||||
!strstr(data->url.get(), "&header=filter") &&
|
||||
!strstr(data->url.get(), "?header=attach") &&
|
||||
!strstr(data->url.get(), "&header=attach")) {
|
||||
nsCOMPtr<nsIMailChannel> mailChannel = do_QueryInterface(channel);
|
||||
if (mailChannel) {
|
||||
mailChannel->GetSmimeSink(getter_AddRefs(data->smimeSink));
|
||||
if (!strstr(data->url.get(), "?header=filter") &&
|
||||
!strstr(data->url.get(), "&header=filter") &&
|
||||
!strstr(data->url.get(), "?header=attach") &&
|
||||
!strstr(data->url.get(), "&header=attach")) {
|
||||
nsCOMPtr<nsIMailChannel> mailChannel = do_QueryInterface(channel);
|
||||
if (mailChannel) {
|
||||
mailChannel->GetSmimeSink(getter_AddRefs(data->smimeSink));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if channel
|
||||
} // if channel
|
||||
} // if isMimeStreamData
|
||||
} // if msd
|
||||
|
||||
return data;
|
||||
return MimeClosure(MimeClosure::isMimeCMSData, data);
|
||||
}
|
||||
|
||||
static int MimeCMS_write(const char* buf, int32_t buf_size, void* closure) {
|
||||
MimeCMSdata* data = (MimeCMSdata*)closure;
|
||||
static int MimeCMS_write(const char* buf, int32_t buf_size,
|
||||
MimeClosure closure) {
|
||||
if (!closure) return -1;
|
||||
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeCMSData);
|
||||
if (closure.mType != MimeClosure::isMimeCMSData) {
|
||||
return -1;
|
||||
}
|
||||
MimeCMSdata* data = (MimeCMSdata*)closure.mClosure;
|
||||
nsresult rv;
|
||||
|
||||
if (!data || !data->output_fn || !data->decoder_context) return -1;
|
||||
|
@ -681,12 +712,20 @@ static const char* bufferContains2Newlines(const char* buf, size_t len) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static int MimeCMS_eof(void* crypto_closure, bool abort_p) {
|
||||
MimeCMSdata* data = (MimeCMSdata*)crypto_closure;
|
||||
static int MimeCMS_eof(MimeClosure crypto_closure, bool abort_p) {
|
||||
if (!crypto_closure) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeCMSData) {
|
||||
return -1;
|
||||
}
|
||||
MimeCMSdata* data = (MimeCMSdata*)crypto_closure.mClosure;
|
||||
nsresult rv;
|
||||
int32_t status = nsICMSMessageErrors::SUCCESS;
|
||||
|
||||
if (!data || !data->output_fn) {
|
||||
if (!data->output_fn) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -830,9 +869,14 @@ static int MimeCMS_eof(void* crypto_closure, bool abort_p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void MimeCMS_free(void* crypto_closure) {
|
||||
MimeCMSdata* data = (MimeCMSdata*)crypto_closure;
|
||||
if (!data) return;
|
||||
static void MimeCMS_free(MimeClosure crypto_closure) {
|
||||
if (!crypto_closure) return;
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeCMSData) {
|
||||
return;
|
||||
}
|
||||
MimeCMSdata* data = (MimeCMSdata*)crypto_closure.mClosure;
|
||||
|
||||
if (data->decoded_buffer) {
|
||||
PR_Free(data->decoded_buffer);
|
||||
|
@ -842,4 +886,4 @@ static void MimeCMS_free(void* crypto_closure) {
|
|||
delete data;
|
||||
}
|
||||
|
||||
static char* MimeCMS_generate(void* crypto_closure) { return nullptr; }
|
||||
static char* MimeCMS_generate(MimeClosure crypto_closure) { return nullptr; }
|
||||
|
|
|
@ -30,10 +30,10 @@ MimeDefClass(MimeEncrypted, MimeEncryptedClass, mimeEncryptedClass,
|
|||
static int MimeEncrypted_initialize(MimeObject*);
|
||||
static void MimeEncrypted_finalize(MimeObject*);
|
||||
static int MimeEncrypted_parse_begin(MimeObject*);
|
||||
static int MimeEncrypted_parse_buffer(const char*, int32_t, MimeObject*);
|
||||
static int MimeEncrypted_parse_buffer(const char*, int32_t, MimeClosure);
|
||||
static int MimeEncrypted_parse_line(const char*, int32_t, MimeObject*);
|
||||
static int MimeEncrypted_parse_decoded_buffer(const char*, int32_t,
|
||||
MimeObject*);
|
||||
MimeClosure);
|
||||
static int MimeEncrypted_parse_eof(MimeObject*, bool);
|
||||
static int MimeEncrypted_parse_end(MimeObject*, bool);
|
||||
static int MimeEncrypted_add_child(MimeObject*, MimeObject*);
|
||||
|
@ -70,7 +70,7 @@ static int MimeEncrypted_initialize(MimeObject* obj) {
|
|||
|
||||
static int MimeEncrypted_parse_begin(MimeObject* obj) {
|
||||
MimeEncrypted* enc = (MimeEncrypted*)obj;
|
||||
MimeDecoderData* (*fn)(MimeConverterOutputCallback, void*) = 0;
|
||||
MimeDecoderData* (*fn)(MimeConverterOutputCallback, MimeClosure) = 0;
|
||||
|
||||
if (enc->crypto_closure) return -1;
|
||||
|
||||
|
@ -86,13 +86,9 @@ static int MimeEncrypted_parse_begin(MimeObject* obj) {
|
|||
else if (!PL_strcasecmp(obj->encoding, ENCODING_BASE64))
|
||||
fn = &MimeB64DecoderInit;
|
||||
else if (!PL_strcasecmp(obj->encoding, ENCODING_QUOTED_PRINTABLE)) {
|
||||
enc->decoder_data =
|
||||
MimeQPDecoderInit(/* The (MimeConverterOutputCallback) cast is to turn
|
||||
the `void' argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)((MimeEncryptedClass*)
|
||||
obj->clazz)
|
||||
->parse_decoded_buffer),
|
||||
obj);
|
||||
enc->decoder_data = MimeQPDecoderInit(
|
||||
((MimeEncryptedClass*)obj->clazz)->parse_decoded_buffer,
|
||||
MimeClosure(MimeClosure::isMimeObject, obj));
|
||||
|
||||
if (!enc->decoder_data) return MIME_OUT_OF_MEMORY;
|
||||
} else if (!PL_strcasecmp(obj->encoding, ENCODING_UUENCODE) ||
|
||||
|
@ -104,11 +100,8 @@ static int MimeEncrypted_parse_begin(MimeObject* obj) {
|
|||
fn = &MimeYDecoderInit;
|
||||
if (fn) {
|
||||
enc->decoder_data =
|
||||
fn(/* The (MimeConverterOutputCallback) cast is to turn the `void'
|
||||
argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)((MimeEncryptedClass*)obj->clazz)
|
||||
->parse_decoded_buffer),
|
||||
obj);
|
||||
fn((((MimeEncryptedClass*)obj->clazz)->parse_decoded_buffer),
|
||||
MimeClosure(MimeClosure::isMimeObject, obj));
|
||||
|
||||
if (!enc->decoder_data) return MIME_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -117,9 +110,14 @@ static int MimeEncrypted_parse_begin(MimeObject* obj) {
|
|||
}
|
||||
|
||||
static int MimeEncrypted_parse_buffer(const char* buffer, int32_t size,
|
||||
MimeObject* obj) {
|
||||
MimeClosure closure) {
|
||||
/* (Duplicated from MimeLeaf, see comments in mimecryp.h.)
|
||||
*/
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeObject);
|
||||
if (closure.mType != MimeClosure::isMimeObject) {
|
||||
return -1;
|
||||
}
|
||||
MimeObject* obj = (MimeObject*)closure.mClosure;
|
||||
|
||||
MimeEncrypted* enc = (MimeEncrypted*)obj;
|
||||
|
||||
|
@ -133,7 +131,8 @@ static int MimeEncrypted_parse_buffer(const char* buffer, int32_t size,
|
|||
return MimeDecoderWrite(enc->decoder_data, buffer, size, nullptr);
|
||||
else
|
||||
return ((MimeEncryptedClass*)obj->clazz)
|
||||
->parse_decoded_buffer(buffer, size, obj);
|
||||
->parse_decoded_buffer(buffer, size,
|
||||
MimeClosure(MimeClosure::isMimeObject, obj));
|
||||
}
|
||||
|
||||
static int MimeEncrypted_parse_line(const char* line, int32_t length,
|
||||
|
@ -143,8 +142,13 @@ static int MimeEncrypted_parse_line(const char* line, int32_t length,
|
|||
}
|
||||
|
||||
static int MimeEncrypted_parse_decoded_buffer(const char* buffer, int32_t size,
|
||||
MimeObject* obj) {
|
||||
MimeEncrypted* enc = (MimeEncrypted*)obj;
|
||||
MimeClosure closure) {
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeObject);
|
||||
if (closure.mType != MimeClosure::isMimeObject) {
|
||||
return -1;
|
||||
}
|
||||
MimeObject* obj = (MimeObject*)closure.mClosure;
|
||||
MimeEncrypted* enc = (MimeEncrypted*)closure.mClosure;
|
||||
return ((MimeEncryptedClass*)obj->clazz)
|
||||
->crypto_write(buffer, size, enc->crypto_closure);
|
||||
}
|
||||
|
@ -224,7 +228,7 @@ static void MimeEncrypted_cleanup(MimeObject* obj, bool finalizing_p) {
|
|||
around for the lifetime of the MIME object, so that we can get at the
|
||||
security info of sub-parts of the currently-displayed message. */
|
||||
((MimeEncryptedClass*)obj->clazz)->crypto_free(enc->crypto_closure);
|
||||
enc->crypto_closure = 0;
|
||||
enc->crypto_closure = MimeClosure::zero();
|
||||
}
|
||||
|
||||
/* (Duplicated from MimeLeaf, see comments in mimecryp.h.)
|
||||
|
@ -340,7 +344,7 @@ static int MimeEncrypted_add_child(MimeObject* parent, MimeObject* child) {
|
|||
}
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
static int DebugOut(const char* buf, int32_t size, void* closure) {
|
||||
static int DebugOut(const char* buf, int32_t size, MimeClosure closure) {
|
||||
MOZ_LOG(gMimeCryptLog, LogLevel::Debug,
|
||||
("MimeEncrypted_emit_buffered_child: (partial) decrypted body\n%.*s",
|
||||
size, buf));
|
||||
|
@ -365,7 +369,8 @@ static int MimeEncrypted_emit_buffered_child(MimeObject* obj) {
|
|||
}
|
||||
|
||||
if (enc->part_buffer) {
|
||||
status = MimePartBufferRead(enc->part_buffer, DebugOut, 0);
|
||||
status = MimePartBufferRead(enc->part_buffer, DebugOut,
|
||||
MimeClosure(MimeClosure::isUndefined, 0));
|
||||
if (status < 0) return status;
|
||||
}
|
||||
#endif
|
||||
|
@ -463,20 +468,14 @@ static int MimeEncrypted_emit_buffered_child(MimeObject* obj) {
|
|||
{
|
||||
#ifdef MIME_DRAFTS
|
||||
if (obj->options->decompose_file_p && !obj->options->is_multipart_msg) {
|
||||
status = MimePartBufferRead(
|
||||
enc->part_buffer,
|
||||
/* The (MimeConverterOutputCallback) cast is to turn the `void'
|
||||
argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)obj->options->decompose_file_output_fn),
|
||||
obj->options->stream_closure);
|
||||
status = MimePartBufferRead(enc->part_buffer,
|
||||
obj->options->decompose_file_output_fn,
|
||||
obj->options->stream_closure);
|
||||
} else {
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
||||
status = MimePartBufferRead(
|
||||
enc->part_buffer,
|
||||
/* The (MimeConverterOutputCallback) cast is to turn the `void'
|
||||
argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)body->clazz->parse_buffer), body);
|
||||
status = MimePartBufferRead(enc->part_buffer, body->clazz->parse_buffer,
|
||||
MimeClosure(MimeClosure::isMimeObject, body));
|
||||
#ifdef MIME_DRAFTS
|
||||
}
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
|
|
@ -105,25 +105,27 @@ struct MimeEncryptedClass {
|
|||
|
||||
/* Duplicated from MimeLeaf, see comments above.
|
||||
This is the callback that is handed to the decoder. */
|
||||
int (*parse_decoded_buffer)(const char* buf, int32_t size, MimeObject* obj);
|
||||
int (*parse_decoded_buffer)(const char* buf, int32_t size,
|
||||
MimeClosure closure);
|
||||
|
||||
/* Callbacks used by decryption module. */
|
||||
void* (*crypto_init)(MimeObject* obj,
|
||||
int (*output_fn)(const char* data, int32_t data_size,
|
||||
void* output_closure),
|
||||
void* output_closure);
|
||||
MimeClosure (*crypto_init)(MimeObject* obj,
|
||||
int (*output_fn)(const char* data,
|
||||
int32_t data_size,
|
||||
void* output_closure),
|
||||
void* output_closure);
|
||||
int (*crypto_write)(const char* data, int32_t data_size,
|
||||
void* crypto_closure);
|
||||
int (*crypto_eof)(void* crypto_closure, bool abort_p);
|
||||
char* (*crypto_generate_html)(void* crypto_closure);
|
||||
void (*crypto_free)(void* crypto_closure);
|
||||
MimeClosure crypto_closure);
|
||||
int (*crypto_eof)(MimeClosure crypto_closure, bool abort_p);
|
||||
char* (*crypto_generate_html)(MimeClosure crypto_closure);
|
||||
void (*crypto_free)(MimeClosure crypto_closure);
|
||||
};
|
||||
|
||||
extern MimeEncryptedClass mimeEncryptedClass;
|
||||
|
||||
struct MimeEncrypted {
|
||||
MimeContainer container; /* superclass variables */
|
||||
void* crypto_closure; /* Opaque data used by decryption module. */
|
||||
MimeClosure crypto_closure; /* Opaque data used by decryption module. */
|
||||
MimeDecoderData* decoder_data; /* Opaque data for the Transfer-Encoding
|
||||
decoder. */
|
||||
MimeHeaders* hdrs; /* Headers of the enclosed object (including
|
||||
|
|
|
@ -67,10 +67,11 @@ using namespace mozilla::mailnews;
|
|||
// Forward declarations...
|
||||
//
|
||||
extern "C" char* MIME_StripContinuations(char* original);
|
||||
int mime_decompose_file_init_fn(void* stream_closure, MimeHeaders* headers);
|
||||
int mime_decompose_file_init_fn(MimeClosure stream_closure,
|
||||
MimeHeaders* headers);
|
||||
int mime_decompose_file_output_fn(const char* buf, int32_t size,
|
||||
void* stream_closure);
|
||||
int mime_decompose_file_close_fn(void* stream_closure);
|
||||
MimeClosure stream_closure);
|
||||
int mime_decompose_file_close_fn(MimeClosure stream_closure);
|
||||
extern int MimeHeaders_build_heads_list(MimeHeaders* hdrs);
|
||||
|
||||
#define NS_MSGCOMPOSESERVICE_CID \
|
||||
|
@ -404,12 +405,18 @@ nsresult CreateCompositionFields(
|
|||
return rv;
|
||||
}
|
||||
|
||||
static int dummy_file_write(char* buf, int32_t size, void* fileHandle) {
|
||||
if (!fileHandle) return -1;
|
||||
static int dummy_file_write(const char* buf, int32_t size,
|
||||
MimeClosure draftData) {
|
||||
if (!draftData) return -1;
|
||||
|
||||
PR_ASSERT(draftData.mType == MimeClosure::isMimeDraftData);
|
||||
if (draftData.mType != MimeClosure::isMimeDraftData) {
|
||||
return -1;
|
||||
}
|
||||
mime_draft_data* mdd = (mime_draft_data*)draftData.mClosure;
|
||||
|
||||
nsIOutputStream* tStream = (nsIOutputStream*)fileHandle;
|
||||
uint32_t bytesWritten;
|
||||
tStream->Write(buf, size, &bytesWritten);
|
||||
mdd->tmpFileStream->Write(buf, size, &bytesWritten);
|
||||
return (int)bytesWritten;
|
||||
}
|
||||
|
||||
|
@ -420,7 +427,8 @@ static int mime_parse_stream_write(nsMIMESession* stream, const char* buf,
|
|||
|
||||
if (!mdd || !mdd->obj) return -1;
|
||||
|
||||
return mdd->obj->clazz->parse_buffer((char*)buf, size, mdd->obj);
|
||||
return mdd->obj->clazz->parse_buffer(
|
||||
(char*)buf, size, MimeClosure(MimeClosure::isMimeObject, mdd->obj));
|
||||
}
|
||||
|
||||
static void mime_free_attachments(nsTArray<nsMsgAttachedFile*>& attachments) {
|
||||
|
@ -1708,12 +1716,15 @@ static void mime_parse_stream_abort(nsMIMESession* stream, int status) {
|
|||
PR_Free(mdd);
|
||||
}
|
||||
|
||||
static int make_mime_headers_copy(void* closure, MimeHeaders* headers) {
|
||||
mime_draft_data* mdd = (mime_draft_data*)closure;
|
||||
static int make_mime_headers_copy(MimeClosure closure, MimeHeaders* headers) {
|
||||
NS_ASSERTION(closure && headers, "null mime draft data and/or headers");
|
||||
if (!closure || !headers) return 0;
|
||||
|
||||
NS_ASSERTION(mdd && headers, "null mime draft data and/or headers");
|
||||
|
||||
if (!mdd || !headers) return 0;
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeDraftData);
|
||||
if (closure.mType != MimeClosure::isMimeDraftData) {
|
||||
return 0;
|
||||
}
|
||||
mime_draft_data* mdd = (mime_draft_data*)closure.mClosure;
|
||||
|
||||
NS_ASSERTION(mdd->headers == NULL, "non null mime draft data headers");
|
||||
|
||||
|
@ -1723,17 +1734,23 @@ static int make_mime_headers_copy(void* closure, MimeHeaders* headers) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mime_decompose_file_init_fn(void* stream_closure, MimeHeaders* headers) {
|
||||
mime_draft_data* mdd = (mime_draft_data*)stream_closure;
|
||||
int mime_decompose_file_init_fn(MimeClosure stream_closure,
|
||||
MimeHeaders* headers) {
|
||||
NS_ASSERTION(stream_closure && headers,
|
||||
"null mime draft data and/or headers");
|
||||
if (!stream_closure || !headers) return -1;
|
||||
|
||||
PR_ASSERT(stream_closure.mType == MimeClosure::isMimeDraftData);
|
||||
if (stream_closure.mType != MimeClosure::isMimeDraftData) {
|
||||
return -1;
|
||||
}
|
||||
mime_draft_data* mdd = (mime_draft_data*)stream_closure.mClosure;
|
||||
nsMsgAttachedFile* newAttachment = 0;
|
||||
int nAttachments = 0;
|
||||
// char *hdr_value = NULL;
|
||||
char* parm_value = NULL;
|
||||
bool creatingMsgBody = true;
|
||||
|
||||
NS_ASSERTION(mdd && headers, "null mime draft data and/or headers");
|
||||
if (!mdd || !headers) return -1;
|
||||
|
||||
if (mdd->options->decompose_init_count) {
|
||||
mdd->options->decompose_init_count++;
|
||||
NS_ASSERTION(mdd->curAttachment,
|
||||
|
@ -1896,7 +1913,7 @@ int mime_decompose_file_init_fn(void* stream_closure, MimeHeaders* headers) {
|
|||
// For now, we are always going to decode all of the attachments
|
||||
// for the message. This way, we have native data
|
||||
if (creatingMsgBody) {
|
||||
MimeDecoderData* (*fn)(MimeConverterOutputCallback, void*) = 0;
|
||||
MimeDecoderData* (*fn)(MimeConverterOutputCallback, MimeClosure) = 0;
|
||||
|
||||
//
|
||||
// Initialize a decoder if necessary.
|
||||
|
@ -1905,11 +1922,8 @@ int mime_decompose_file_init_fn(void* stream_closure, MimeHeaders* headers) {
|
|||
fn = &MimeB64DecoderInit;
|
||||
else if (newAttachment->m_encoding.LowerCaseEqualsLiteral(
|
||||
ENCODING_QUOTED_PRINTABLE)) {
|
||||
mdd->decoder_data =
|
||||
MimeQPDecoderInit(/* The (MimeConverterOutputCallback) cast is to turn
|
||||
the `void' argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)dummy_file_write),
|
||||
mdd->tmpFileStream);
|
||||
mdd->decoder_data = MimeQPDecoderInit(
|
||||
dummy_file_write, MimeClosure(MimeClosure::isMimeDraftData, mdd));
|
||||
if (!mdd->decoder_data) return MIME_OUT_OF_MEMORY;
|
||||
} else if (newAttachment->m_encoding.LowerCaseEqualsLiteral(
|
||||
ENCODING_UUENCODE) ||
|
||||
|
@ -1924,10 +1938,8 @@ int mime_decompose_file_init_fn(void* stream_closure, MimeHeaders* headers) {
|
|||
fn = &MimeYDecoderInit;
|
||||
|
||||
if (fn) {
|
||||
mdd->decoder_data = fn(/* The (MimeConverterOutputCallback) cast is to
|
||||
turn the `void' argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)dummy_file_write),
|
||||
mdd->tmpFileStream);
|
||||
mdd->decoder_data =
|
||||
fn(dummy_file_write, MimeClosure(MimeClosure::isMimeDraftData, mdd));
|
||||
if (!mdd->decoder_data) return MIME_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -1936,12 +1948,17 @@ int mime_decompose_file_init_fn(void* stream_closure, MimeHeaders* headers) {
|
|||
}
|
||||
|
||||
int mime_decompose_file_output_fn(const char* buf, int32_t size,
|
||||
void* stream_closure) {
|
||||
mime_draft_data* mdd = (mime_draft_data*)stream_closure;
|
||||
MimeClosure stream_closure) {
|
||||
NS_ASSERTION(stream_closure && buf, "missing mime draft data and/or buf");
|
||||
if (!stream_closure || !buf) return -1;
|
||||
|
||||
PR_ASSERT(stream_closure.mType == MimeClosure::isMimeDraftData);
|
||||
if (stream_closure.mType != MimeClosure::isMimeDraftData) {
|
||||
return -1;
|
||||
}
|
||||
mime_draft_data* mdd = (mime_draft_data*)stream_closure.mClosure;
|
||||
int ret = 0;
|
||||
|
||||
NS_ASSERTION(mdd && buf, "missing mime draft data and/or buf");
|
||||
if (!mdd || !buf) return -1;
|
||||
if (!size) return 0;
|
||||
|
||||
if (!mdd->tmpFileStream) return 0;
|
||||
|
@ -1971,10 +1988,14 @@ int mime_decompose_file_output_fn(const char* buf, int32_t size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mime_decompose_file_close_fn(void* stream_closure) {
|
||||
mime_draft_data* mdd = (mime_draft_data*)stream_closure;
|
||||
int mime_decompose_file_close_fn(MimeClosure stream_closure) {
|
||||
if (!stream_closure) return -1;
|
||||
|
||||
if (!mdd) return -1;
|
||||
PR_ASSERT(stream_closure.mType == MimeClosure::isMimeDraftData);
|
||||
if (stream_closure.mType != MimeClosure::isMimeDraftData) {
|
||||
return -1;
|
||||
}
|
||||
mime_draft_data* mdd = (mime_draft_data*)stream_closure.mClosure;
|
||||
|
||||
if (--mdd->options->decompose_init_count > 0) return 0;
|
||||
|
||||
|
@ -2050,7 +2071,7 @@ extern "C" void* mime_bridge_create_draft_stream(
|
|||
mdd->options->url = strdup(mdd->url_name);
|
||||
mdd->options->format_out = format_out; // output format
|
||||
mdd->options->decompose_file_p = true; /* new field in MimeDisplayOptions */
|
||||
mdd->options->stream_closure = mdd;
|
||||
mdd->options->stream_closure = MimeClosure(MimeClosure::isMimeDraftData, mdd);
|
||||
mdd->options->html_closure = mdd;
|
||||
mdd->options->decompose_headers_info_fn = make_mime_headers_copy;
|
||||
mdd->options->decompose_file_init_fn = mime_decompose_file_init_fn;
|
||||
|
|
|
@ -38,7 +38,7 @@ struct MimeDecoderData {
|
|||
MimeObject* objectToDecode; // might be null, only used for QP currently
|
||||
/* Where to write the decoded data */
|
||||
MimeConverterOutputCallback write_buffer;
|
||||
void* closure;
|
||||
MimeClosure closure;
|
||||
};
|
||||
|
||||
static int mime_decode_qp_buffer(MimeDecoderData* data, const char* buffer,
|
||||
|
@ -697,7 +697,7 @@ int MimeDecoderDestroy(MimeDecoderData* data, bool abort_p) {
|
|||
|
||||
static MimeDecoderData* mime_decoder_init(mime_encoding which,
|
||||
MimeConverterOutputCallback output_fn,
|
||||
void* closure) {
|
||||
MimeClosure closure) {
|
||||
MimeDecoderData* data = PR_NEW(MimeDecoderData);
|
||||
if (!data) return 0;
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
@ -711,12 +711,12 @@ static MimeDecoderData* mime_decoder_init(mime_encoding which,
|
|||
}
|
||||
|
||||
MimeDecoderData* MimeB64DecoderInit(MimeConverterOutputCallback output_fn,
|
||||
void* closure) {
|
||||
MimeClosure closure) {
|
||||
return mime_decoder_init(mime_Base64, output_fn, closure);
|
||||
}
|
||||
|
||||
MimeDecoderData* MimeQPDecoderInit(MimeConverterOutputCallback output_fn,
|
||||
void* closure, MimeObject* object) {
|
||||
MimeClosure closure, MimeObject* object) {
|
||||
MimeDecoderData* retData =
|
||||
mime_decoder_init(mime_QuotedPrintable, output_fn, closure);
|
||||
if (retData) retData->objectToDecode = object;
|
||||
|
@ -724,12 +724,12 @@ MimeDecoderData* MimeQPDecoderInit(MimeConverterOutputCallback output_fn,
|
|||
}
|
||||
|
||||
MimeDecoderData* MimeUUDecoderInit(MimeConverterOutputCallback output_fn,
|
||||
void* closure) {
|
||||
MimeClosure closure) {
|
||||
return mime_decoder_init(mime_uuencode, output_fn, closure);
|
||||
}
|
||||
|
||||
MimeDecoderData* MimeYDecoderInit(MimeConverterOutputCallback output_fn,
|
||||
void* closure) {
|
||||
MimeClosure closure) {
|
||||
return mime_decoder_init(mime_yencode, output_fn, closure);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@ MimeDefClass(MimeExternalObject, MimeExternalObjectClass,
|
|||
static int MimeExternalObject_initialize(MimeObject*);
|
||||
static void MimeExternalObject_finalize(MimeObject*);
|
||||
static int MimeExternalObject_parse_begin(MimeObject*);
|
||||
static int MimeExternalObject_parse_buffer(const char*, int32_t, MimeObject*);
|
||||
static int MimeExternalObject_parse_buffer(const char*, int32_t, MimeClosure);
|
||||
static int MimeExternalObject_parse_line(const char*, int32_t, MimeObject*);
|
||||
static int MimeExternalObject_parse_decoded_buffer(const char*, int32_t,
|
||||
MimeObject*);
|
||||
MimeClosure);
|
||||
static bool MimeExternalObject_displayable_inline_p(MimeObjectClass* clazz,
|
||||
MimeHeaders* hdrs);
|
||||
|
||||
|
@ -148,7 +148,13 @@ static int MimeExternalObject_parse_begin(MimeObject* obj) {
|
|||
}
|
||||
|
||||
static int MimeExternalObject_parse_buffer(const char* buffer, int32_t size,
|
||||
MimeObject* obj) {
|
||||
MimeClosure closure) {
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeObject);
|
||||
if (closure.mType != MimeClosure::isMimeObject) {
|
||||
return -1;
|
||||
}
|
||||
MimeObject* obj = (MimeObject*)closure.mClosure;
|
||||
|
||||
NS_ASSERTION(!obj->closed_p, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
|
||||
if (obj->closed_p) return -1;
|
||||
|
||||
|
@ -157,12 +163,13 @@ static int MimeExternalObject_parse_buffer(const char* buffer, int32_t size,
|
|||
|
||||
/* The data will be base64-decoded and passed to
|
||||
MimeExternalObject_parse_decoded_buffer. */
|
||||
return ((MimeObjectClass*)&MIME_SUPERCLASS)->parse_buffer(buffer, size, obj);
|
||||
return ((MimeObjectClass*)&MIME_SUPERCLASS)
|
||||
->parse_buffer(buffer, size, closure);
|
||||
}
|
||||
|
||||
static int MimeExternalObject_parse_decoded_buffer(const char* buf,
|
||||
int32_t size,
|
||||
MimeObject* obj) {
|
||||
MimeClosure closure) {
|
||||
/* This is called (by MimeLeafClass->parse_buffer) with blocks of data
|
||||
that have already been base64-decoded. This will only be called in
|
||||
the case where we're not emitting HTML, and want access to the raw
|
||||
|
@ -180,6 +187,12 @@ static int MimeExternalObject_parse_decoded_buffer(const char* buf,
|
|||
* reading them) and the JS emitter (which doesn't care about attachment data
|
||||
* at all). 0 means ok, the caller just checks for negative return value.
|
||||
*/
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeObject);
|
||||
if (closure.mType != MimeClosure::isMimeObject) {
|
||||
return -1;
|
||||
}
|
||||
MimeObject* obj = (MimeObject*)closure.mClosure;
|
||||
|
||||
if (obj->options &&
|
||||
(obj->options->metadata_only || obj->options->write_html_p))
|
||||
return 0;
|
||||
|
|
|
@ -306,8 +306,14 @@ void getMsgHdrForCurrentURL(MimeDisplayOptions* opts, nsIMsgDBHdr** aMsgHdr) {
|
|||
|
||||
if (!opts) return;
|
||||
|
||||
mime_stream_data* msd = (mime_stream_data*)(opts->stream_closure);
|
||||
if (!msd) return;
|
||||
if (!opts->stream_closure) return;
|
||||
|
||||
PR_ASSERT(opts->stream_closure.mType == MimeClosure::isMimeStreamData ||
|
||||
opts->stream_closure.mType == MimeClosure::isMimeDraftData);
|
||||
if (opts->stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return;
|
||||
}
|
||||
mime_stream_data* msd = (mime_stream_data*)(opts->stream_closure.mClosure);
|
||||
|
||||
nsCOMPtr<nsIChannel> channel =
|
||||
msd->channel; // note the lack of ref counting...
|
||||
|
@ -417,11 +423,16 @@ MimeObjectClass* mime_find_class(const char* content_type, MimeHeaders* hdrs,
|
|||
char* imip_method = MimeHeaders_get_parameter(
|
||||
full_content_type, "method", nullptr, nullptr);
|
||||
|
||||
mime_stream_data* msd = (mime_stream_data*)(opts->stream_closure);
|
||||
nsCOMPtr<nsIMailChannel> mailChannel = do_QueryInterface(msd->channel);
|
||||
if (mailChannel) {
|
||||
mailChannel->SetImipMethod(
|
||||
nsDependentCString(imip_method ? imip_method : "nomethod"));
|
||||
PR_ASSERT(opts->stream_closure.mType == MimeClosure::isMimeStreamData);
|
||||
if (opts->stream_closure.mType == MimeClosure::isMimeStreamData) {
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(opts->stream_closure.mClosure);
|
||||
nsCOMPtr<nsIMailChannel> mailChannel =
|
||||
do_QueryInterface(msd->channel);
|
||||
if (mailChannel) {
|
||||
mailChannel->SetImipMethod(
|
||||
nsDependentCString(imip_method ? imip_method : "nomethod"));
|
||||
}
|
||||
}
|
||||
|
||||
// PR_Free checks for null
|
||||
|
@ -1516,11 +1527,11 @@ int mime_parse_url_options(const char* url, MimeDisplayOptions* options) {
|
|||
int MimeOptions_write(MimeHeaders* hdrs, MimeDisplayOptions* opt,
|
||||
const char* data, int32_t length, bool user_visible_p) {
|
||||
int status = 0;
|
||||
void* closure = 0;
|
||||
MimeClosure closure;
|
||||
if (!opt || !opt->output_fn || !opt->state) return 0;
|
||||
|
||||
closure = opt->output_closure;
|
||||
if (!closure) closure = opt->stream_closure;
|
||||
if (!closure.mClosure) closure = opt->stream_closure;
|
||||
|
||||
// PR_ASSERT(opt->state->first_data_written_p);
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ static int MimeInlineImage_parse_begin(MimeObject*);
|
|||
static int MimeInlineImage_parse_line(const char*, int32_t, MimeObject*);
|
||||
static int MimeInlineImage_parse_eof(MimeObject*, bool);
|
||||
static int MimeInlineImage_parse_decoded_buffer(const char*, int32_t,
|
||||
MimeObject*);
|
||||
MimeClosure);
|
||||
|
||||
static int MimeInlineImageClassInitialize(MimeObjectClass* oclass) {
|
||||
MimeLeafClass* lclass = (MimeLeafClass*)oclass;
|
||||
|
@ -129,8 +129,14 @@ static int MimeInlineImage_parse_begin(MimeObject* obj) {
|
|||
// URI for the url being run...
|
||||
//
|
||||
if (obj->options && obj->options->stream_closure && obj->content_type) {
|
||||
mime_stream_data* msd = (mime_stream_data*)(obj->options->stream_closure);
|
||||
if ((msd) && (msd->channel)) {
|
||||
PR_ASSERT(obj->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData);
|
||||
if (obj->options->stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return -1;
|
||||
}
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(obj->options->stream_closure.mClosure);
|
||||
if (msd->channel) {
|
||||
msd->channel->SetContentType(nsDependentCString(obj->content_type));
|
||||
}
|
||||
}
|
||||
|
@ -157,11 +163,17 @@ static int MimeInlineImage_parse_eof(MimeObject* obj, bool abort_p) {
|
|||
}
|
||||
|
||||
static int MimeInlineImage_parse_decoded_buffer(const char* buf, int32_t size,
|
||||
MimeObject* obj) {
|
||||
MimeClosure closure) {
|
||||
/* This is called (by MimeLeafClass->parse_buffer) with blocks of data
|
||||
that have already been base64-decoded. Pass this raw image data
|
||||
along to the backend-specific image display code.
|
||||
*/
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeObject);
|
||||
if (closure.mType != MimeClosure::isMimeObject) {
|
||||
return -1;
|
||||
}
|
||||
MimeObject* obj = (MimeObject*)closure.mClosure;
|
||||
|
||||
MimeInlineImage* img = (MimeInlineImage*)obj;
|
||||
int status;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ MimeDefClass(MimeLeaf, MimeLeafClass, mimeLeafClass, &MIME_SUPERCLASS);
|
|||
static int MimeLeaf_initialize(MimeObject*);
|
||||
static void MimeLeaf_finalize(MimeObject*);
|
||||
static int MimeLeaf_parse_begin(MimeObject*);
|
||||
static int MimeLeaf_parse_buffer(const char*, int32_t, MimeObject*);
|
||||
static int MimeLeaf_parse_buffer(const char*, int32_t, MimeClosure);
|
||||
static int MimeLeaf_parse_line(const char*, int32_t, MimeObject*);
|
||||
static int MimeLeaf_close_decoder(MimeObject*);
|
||||
static int MimeLeaf_parse_eof(MimeObject*, bool);
|
||||
|
@ -78,7 +78,7 @@ static void MimeLeaf_finalize(MimeObject* object) {
|
|||
|
||||
static int MimeLeaf_parse_begin(MimeObject* obj) {
|
||||
MimeLeaf* leaf = (MimeLeaf*)obj;
|
||||
MimeDecoderData* (*fn)(MimeConverterOutputCallback, void*) = 0;
|
||||
MimeDecoderData* (*fn)(MimeConverterOutputCallback, MimeClosure) = 0;
|
||||
|
||||
/* Initialize a decoder if necessary.
|
||||
*/
|
||||
|
@ -92,10 +92,9 @@ static int MimeLeaf_parse_begin(MimeObject* obj) {
|
|||
else if (!PL_strcasecmp(obj->encoding, ENCODING_BASE64))
|
||||
fn = &MimeB64DecoderInit;
|
||||
else if (!PL_strcasecmp(obj->encoding, ENCODING_QUOTED_PRINTABLE))
|
||||
leaf->decoder_data = MimeQPDecoderInit(
|
||||
((MimeConverterOutputCallback)((MimeLeafClass*)obj->clazz)
|
||||
->parse_decoded_buffer),
|
||||
obj, obj);
|
||||
leaf->decoder_data =
|
||||
MimeQPDecoderInit(((MimeLeafClass*)obj->clazz)->parse_decoded_buffer,
|
||||
MimeClosure(MimeClosure::isMimeObject, obj), obj);
|
||||
else if (!PL_strcasecmp(obj->encoding, ENCODING_UUENCODE) ||
|
||||
!PL_strcasecmp(obj->encoding, ENCODING_UUENCODE2) ||
|
||||
!PL_strcasecmp(obj->encoding, ENCODING_UUENCODE3) ||
|
||||
|
@ -105,12 +104,8 @@ static int MimeLeaf_parse_begin(MimeObject* obj) {
|
|||
fn = &MimeYDecoderInit;
|
||||
|
||||
if (fn) {
|
||||
leaf->decoder_data =
|
||||
fn(/* The MimeConverterOutputCallback cast is to turn the `void'
|
||||
argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)((MimeLeafClass*)obj->clazz)
|
||||
->parse_decoded_buffer),
|
||||
obj);
|
||||
leaf->decoder_data = fn(((MimeLeafClass*)obj->clazz)->parse_decoded_buffer,
|
||||
MimeClosure(MimeClosure::isMimeObject, obj));
|
||||
|
||||
if (!leaf->decoder_data) return MIME_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -119,7 +114,12 @@ static int MimeLeaf_parse_begin(MimeObject* obj) {
|
|||
}
|
||||
|
||||
static int MimeLeaf_parse_buffer(const char* buffer, int32_t size,
|
||||
MimeObject* obj) {
|
||||
MimeClosure closure) {
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeObject);
|
||||
if (closure.mType != MimeClosure::isMimeObject) {
|
||||
return -1;
|
||||
}
|
||||
MimeObject* obj = (MimeObject*)closure.mClosure;
|
||||
MimeLeaf* leaf = (MimeLeaf*)obj;
|
||||
|
||||
NS_ASSERTION(!obj->closed_p, "1.1 <rhp@netscape.com> 19 Mar 1999 12:00");
|
||||
|
@ -139,7 +139,9 @@ static int MimeLeaf_parse_buffer(const char* buffer, int32_t size,
|
|||
rv = MimeDecoderWrite(leaf->decoder_data, buffer, size, &outSize);
|
||||
leaf->sizeSoFar += outSize;
|
||||
} else {
|
||||
rv = ((MimeLeafClass*)obj->clazz)->parse_decoded_buffer(buffer, size, obj);
|
||||
rv = ((MimeLeafClass*)obj->clazz)
|
||||
->parse_decoded_buffer(
|
||||
buffer, size, MimeClosure(MimeClosure::isMimeObject, obj));
|
||||
leaf->sizeSoFar += size;
|
||||
}
|
||||
return rv;
|
||||
|
|
|
@ -35,7 +35,8 @@ typedef struct MimeLeaf MimeLeaf;
|
|||
struct MimeLeafClass {
|
||||
MimeObjectClass object;
|
||||
/* This is the callback that is handed to the decoder. */
|
||||
int (*parse_decoded_buffer)(const char* buf, int32_t size, MimeObject* obj);
|
||||
int (*parse_decoded_buffer)(const char* buf, int32_t size,
|
||||
MimeClosure closure);
|
||||
int (*close_decoder)(MimeObject* obj);
|
||||
};
|
||||
|
||||
|
@ -55,6 +56,6 @@ struct MimeLeaf {
|
|||
};
|
||||
|
||||
#define MimeLeafClassInitializer(ITYPE, CSUPER) \
|
||||
{ MimeObjectClassInitializer(ITYPE, CSUPER) }
|
||||
{MimeObjectClassInitializer(ITYPE, CSUPER)}
|
||||
|
||||
#endif /* _MIMELEAF_H_ */
|
||||
|
|
|
@ -520,11 +520,8 @@ static int MimeMultipartAlternative_display_cached_part(
|
|||
else
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
||||
status = MimePartBufferRead(
|
||||
buffer,
|
||||
/* The MimeConverterOutputCallback cast is to turn the
|
||||
`void' argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)body->clazz->parse_buffer), body);
|
||||
status = MimePartBufferRead(buffer, body->clazz->parse_buffer,
|
||||
MimeClosure(MimeClosure::isMimeObject, body));
|
||||
|
||||
if (status < 0) return status;
|
||||
|
||||
|
|
|
@ -27,16 +27,16 @@ MimeDefClass(MimeMultipartSignedCMS, MimeMultipartSignedCMSClass,
|
|||
|
||||
static int MimeMultipartSignedCMS_initialize(MimeObject*);
|
||||
|
||||
static void* MimeMultCMS_init(MimeObject*);
|
||||
static int MimeMultCMS_data_hash(const char*, int32_t, void*);
|
||||
static int MimeMultCMS_sig_hash(const char*, int32_t, void*);
|
||||
static int MimeMultCMS_data_eof(void*, bool);
|
||||
static int MimeMultCMS_sig_eof(void*, bool);
|
||||
static int MimeMultCMS_sig_init(void*, MimeObject*, MimeHeaders*);
|
||||
static int MimeMultCMS_sig_ignore(void* crypto_closure);
|
||||
static char* MimeMultCMS_generate(void*);
|
||||
static void MimeMultCMS_free(void*);
|
||||
static void MimeMultCMS_suppressed_child(void* crypto_closure);
|
||||
static MimeClosure MimeMultCMS_init(MimeObject*);
|
||||
static int MimeMultCMS_data_hash(const char*, int32_t, MimeClosure);
|
||||
static int MimeMultCMS_sig_hash(const char*, int32_t, MimeClosure);
|
||||
static int MimeMultCMS_data_eof(MimeClosure, bool);
|
||||
static int MimeMultCMS_sig_eof(MimeClosure, bool);
|
||||
static int MimeMultCMS_sig_init(MimeClosure, MimeObject*, MimeHeaders*);
|
||||
static int MimeMultCMS_sig_ignore(MimeClosure crypto_closure);
|
||||
static char* MimeMultCMS_generate(MimeClosure);
|
||||
static void MimeMultCMS_free(MimeClosure);
|
||||
static void MimeMultCMS_suppressed_child(MimeClosure crypto_closure);
|
||||
|
||||
extern int SEC_ERROR_CERT_ADDR_MISMATCH;
|
||||
|
||||
|
@ -118,7 +118,7 @@ extern char* MimeCMS_MakeSAURL(MimeObject* obj);
|
|||
extern char* IMAP_CreateReloadAllPartsUrl(const char* url);
|
||||
extern int MIMEGetRelativeCryptoNestLevel(MimeObject* obj);
|
||||
|
||||
static void* MimeMultCMS_init(MimeObject* obj) {
|
||||
static MimeClosure MimeMultCMS_init(MimeObject* obj) {
|
||||
MimeHeaders* hdrs = obj->headers;
|
||||
MimeMultCMSdata* data = 0;
|
||||
char *ct, *micalg;
|
||||
|
@ -126,13 +126,19 @@ static void* MimeMultCMS_init(MimeObject* obj) {
|
|||
nsresult rv;
|
||||
|
||||
data = new MimeMultCMSdata;
|
||||
if (!data) return 0;
|
||||
if (!data) return MimeClosure(MimeClosure::isUndefined, 0);
|
||||
|
||||
data->self = obj;
|
||||
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(data->self->options->stream_closure);
|
||||
if (msd) {
|
||||
if (data->self->options->stream_closure) {
|
||||
PR_ASSERT(data->self->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData);
|
||||
if (data->self->options->stream_closure.mType !=
|
||||
MimeClosure::isMimeStreamData) {
|
||||
return MimeClosure::zero();
|
||||
}
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(data->self->options->stream_closure.mClosure);
|
||||
nsIChannel* channel = msd->channel; // note the lack of ref counting...
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
@ -188,20 +194,22 @@ static void* MimeMultCMS_init(MimeObject* obj) {
|
|||
nsICMSMessageErrors::GENERAL_ERROR, nullptr,
|
||||
data->url, partnum);
|
||||
}
|
||||
return data;
|
||||
return MimeClosure(MimeClosure::isMimeMultCMSData, data);
|
||||
}
|
||||
|
||||
ct = MimeHeaders_get(hdrs, HEADER_CONTENT_TYPE, false, false);
|
||||
if (!ct) {
|
||||
delete data;
|
||||
return 0; /* #### bogus message? out of memory? */
|
||||
return MimeClosure(MimeClosure::isUndefined,
|
||||
0); /* #### bogus message? out of memory? */
|
||||
}
|
||||
micalg = MimeHeaders_get_parameter(ct, PARAM_MICALG, NULL, NULL);
|
||||
PR_Free(ct);
|
||||
ct = 0;
|
||||
if (!micalg) {
|
||||
delete data;
|
||||
return 0; /* #### bogus message? out of memory? */
|
||||
return MimeClosure(MimeClosure::isUndefined,
|
||||
0); /* #### bogus message? out of memory? */
|
||||
}
|
||||
|
||||
bool allowSha1 = mozilla::Preferences::GetBool(
|
||||
|
@ -236,7 +244,7 @@ static void* MimeMultCMS_init(MimeObject* obj) {
|
|||
data->url, partnum);
|
||||
}
|
||||
PR_Free(micalg);
|
||||
return data;
|
||||
return MimeClosure(MimeClosure::isMimeMultCMSData, data);
|
||||
}
|
||||
|
||||
PR_Free(micalg);
|
||||
|
@ -248,27 +256,32 @@ static void* MimeMultCMS_init(MimeObject* obj) {
|
|||
do_CreateInstance("@mozilla.org/security/hash;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete data;
|
||||
return 0;
|
||||
return MimeClosure(MimeClosure::isUndefined, 0);
|
||||
}
|
||||
|
||||
rv = data->data_hash_context->Init(data->hash_type);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete data;
|
||||
return 0;
|
||||
return MimeClosure(MimeClosure::isUndefined, 0);
|
||||
}
|
||||
|
||||
PR_SetError(0, 0);
|
||||
|
||||
return data;
|
||||
return MimeClosure(MimeClosure::isMimeMultCMSData, data);
|
||||
}
|
||||
|
||||
static int MimeMultCMS_data_hash(const char* buf, int32_t size,
|
||||
void* crypto_closure) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
if (!data) {
|
||||
MimeClosure crypto_closure) {
|
||||
if (!crypto_closure) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return -1;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
|
||||
if (data->reject_signature) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -284,12 +297,17 @@ static int MimeMultCMS_data_hash(const char* buf, int32_t size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int MimeMultCMS_data_eof(void* crypto_closure, bool abort_p) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
if (!data) {
|
||||
static int MimeMultCMS_data_eof(MimeClosure crypto_closure, bool abort_p) {
|
||||
if (!crypto_closure) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return -1;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
|
||||
if (data->reject_signature) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -318,10 +336,14 @@ static int MimeMultCMS_data_eof(void* crypto_closure, bool abort_p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int MimeMultCMS_sig_init(void* crypto_closure,
|
||||
static int MimeMultCMS_sig_init(MimeClosure crypto_closure,
|
||||
MimeObject* multipart_object,
|
||||
MimeHeaders* signature_hdrs) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return -1;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
char* ct;
|
||||
int status = 0;
|
||||
nsresult rv;
|
||||
|
@ -356,36 +378,49 @@ static int MimeMultCMS_sig_init(void* crypto_closure,
|
|||
return status;
|
||||
}
|
||||
|
||||
static int MimeMultCMS_sig_ignore(void* crypto_closure) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
|
||||
if (!data) {
|
||||
static int MimeMultCMS_sig_ignore(MimeClosure crypto_closure) {
|
||||
if (!crypto_closure) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return -1;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
|
||||
data->ignoredLayer = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MimeMultCMSdata_isIgnored(void* crypto_closure) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
|
||||
if (!data) {
|
||||
bool MimeMultCMSdata_isIgnored(MimeClosure crypto_closure) {
|
||||
if (!crypto_closure) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return false;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
|
||||
return data->ignoredLayer;
|
||||
}
|
||||
|
||||
static int MimeMultCMS_sig_hash(const char* buf, int32_t size,
|
||||
void* crypto_closure) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
nsresult rv;
|
||||
|
||||
if (!data) {
|
||||
MimeClosure crypto_closure) {
|
||||
if (!crypto_closure) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return -1;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
nsresult rv;
|
||||
|
||||
if (data->reject_signature) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -400,13 +435,17 @@ static int MimeMultCMS_sig_hash(const char* buf, int32_t size,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int MimeMultCMS_sig_eof(void* crypto_closure, bool abort_p) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
|
||||
if (!data) {
|
||||
static int MimeMultCMS_sig_eof(MimeClosure crypto_closure, bool abort_p) {
|
||||
if (!crypto_closure) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return -1;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
|
||||
if (data->reject_signature) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -427,18 +466,31 @@ static int MimeMultCMS_sig_eof(void* crypto_closure, bool abort_p) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void MimeMultCMS_free(void* crypto_closure) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
if (!data) return;
|
||||
static void MimeMultCMS_free(MimeClosure crypto_closure) {
|
||||
if (!crypto_closure) return;
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
|
||||
delete data;
|
||||
}
|
||||
|
||||
static void MimeMultCMS_suppressed_child(void* crypto_closure) {
|
||||
static void MimeMultCMS_suppressed_child(MimeClosure crypto_closure) {
|
||||
if (!crypto_closure) {
|
||||
return;
|
||||
}
|
||||
|
||||
// I'm a multipart/signed. If one of my cryptographic child elements
|
||||
// was suppressed, then I want my signature to be shown as invalid.
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
if (data && data->smimeSink) {
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
if (data->smimeSink) {
|
||||
if (data->reject_signature || data->ignoredLayer) {
|
||||
return;
|
||||
}
|
||||
|
@ -451,9 +503,14 @@ static void MimeMultCMS_suppressed_child(void* crypto_closure) {
|
|||
}
|
||||
}
|
||||
|
||||
static char* MimeMultCMS_generate(void* crypto_closure) {
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure;
|
||||
if (!data) return 0;
|
||||
static char* MimeMultCMS_generate(MimeClosure crypto_closure) {
|
||||
if (!crypto_closure) return 0;
|
||||
|
||||
PR_ASSERT(crypto_closure.mType == MimeClosure::isMimeMultCMSData);
|
||||
if (crypto_closure.mType != MimeClosure::isMimeMultCMSData) {
|
||||
return nullptr;
|
||||
}
|
||||
MimeMultCMSdata* data = (MimeMultCMSdata*)crypto_closure.mClosure;
|
||||
nsCOMPtr<nsIX509Cert> signerCert;
|
||||
|
||||
int aRelativeNestLevel = MIMEGetRelativeCryptoNestLevel(data->self);
|
||||
|
|
|
@ -32,6 +32,6 @@ struct MimeMultipartSignedCMS {
|
|||
#define MimeMultipartSignedCMSClassInitializer(ITYPE, CSUPER) \
|
||||
{MimeMultipartSignedClassInitializer(ITYPE, CSUPER)}
|
||||
|
||||
bool MimeMultCMSdata_isIgnored(void* crypto_closure);
|
||||
bool MimeMultCMSdata_isIgnored(MimeClosure crypto_closure);
|
||||
|
||||
#endif /* _MIMEMPKC_H_ */
|
||||
|
|
|
@ -693,8 +693,16 @@ extern "C" nsresult SetMailCharacterSetToMsgWindow(MimeObject* obj,
|
|||
nsresult rv = NS_OK;
|
||||
|
||||
if (obj && obj->options) {
|
||||
mime_stream_data* msd = (mime_stream_data*)(obj->options->stream_closure);
|
||||
if (msd) {
|
||||
if (obj->options->stream_closure) {
|
||||
PR_ASSERT(
|
||||
obj->options->stream_closure.mType == MimeClosure::isMimeStreamData ||
|
||||
obj->options->stream_closure.mType == MimeClosure::isMimeDraftData);
|
||||
if (obj->options->stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(obj->options->stream_closure.mClosure);
|
||||
nsCOMPtr<nsIMailChannel> mailChannel = do_QueryInterface(msd->channel);
|
||||
if (mailChannel) {
|
||||
if (!PL_strcasecmp(aCharacterSet, "us-ascii")) {
|
||||
|
@ -709,7 +717,7 @@ extern "C" nsresult SetMailCharacterSetToMsgWindow(MimeObject* obj,
|
|||
return rv;
|
||||
}
|
||||
|
||||
static char* mime_file_type(const char* filename, void* stream_closure) {
|
||||
static char* mime_file_type(const char* filename, MimeClosure stream_closure) {
|
||||
char* retType = nullptr;
|
||||
char* ext = nullptr;
|
||||
nsresult rv;
|
||||
|
@ -762,14 +770,19 @@ int ConvertToUTF8(const char* stringToUse, int32_t inLength,
|
|||
static int mime_convert_charset(const char* input_line, int32_t input_length,
|
||||
const char* input_charset,
|
||||
nsACString& convertedString,
|
||||
void* stream_closure) {
|
||||
MimeClosure stream_closure) {
|
||||
return ConvertToUTF8(input_line, input_length, input_charset,
|
||||
convertedString);
|
||||
}
|
||||
|
||||
static int mime_output_fn(const char* buf, int32_t size, void* stream_closure) {
|
||||
static int mime_output_fn(const char* buf, int32_t size,
|
||||
MimeClosure stream_closure) {
|
||||
uint32_t written = 0;
|
||||
mime_stream_data* msd = (mime_stream_data*)stream_closure;
|
||||
PR_ASSERT(stream_closure.mType == MimeClosure::isMimeStreamData);
|
||||
if (stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return -1;
|
||||
}
|
||||
mime_stream_data* msd = (mime_stream_data*)stream_closure.mClosure;
|
||||
if ((!msd->pluginObj2) && (!msd->output_emitter)) return -1;
|
||||
|
||||
// Fire pending start request
|
||||
|
@ -798,7 +811,8 @@ extern "C" int mime_display_stream_write(nsMIMESession* stream, const char* buf,
|
|||
MimeObject* obj = (msd ? msd->obj : 0);
|
||||
if (!obj) return -1;
|
||||
|
||||
return obj->clazz->parse_buffer((char*)buf, size, obj);
|
||||
return obj->clazz->parse_buffer((char*)buf, size,
|
||||
MimeClosure(MimeClosure::isMimeObject, obj));
|
||||
}
|
||||
|
||||
extern "C" void mime_display_stream_complete(nsMIMESession* stream) {
|
||||
|
@ -884,8 +898,12 @@ extern "C" void mime_display_stream_abort(nsMIMESession* stream, int status) {
|
|||
static int mime_output_init_fn(const char* type, const char* charset,
|
||||
const char* name, const char* x_mac_type,
|
||||
const char* x_mac_creator,
|
||||
void* stream_closure) {
|
||||
mime_stream_data* msd = (mime_stream_data*)stream_closure;
|
||||
MimeClosure stream_closure) {
|
||||
PR_ASSERT(stream_closure.mType == MimeClosure::isMimeStreamData);
|
||||
if (stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return -1;
|
||||
}
|
||||
mime_stream_data* msd = (mime_stream_data*)stream_closure.mClosure;
|
||||
|
||||
// Now, all of this stream creation is done outside of libmime, so this
|
||||
// is just a check of the pluginObj member and returning accordingly.
|
||||
|
@ -896,7 +914,7 @@ static int mime_output_init_fn(const char* type, const char* charset,
|
|||
}
|
||||
|
||||
static void* mime_image_begin(const char* image_url, const char* content_type,
|
||||
void* stream_closure);
|
||||
MimeClosure stream_closure);
|
||||
static void mime_image_end(void* image_closure, int status);
|
||||
static char* mime_image_make_image_html(void* image_data);
|
||||
static int mime_image_write_buffer(const char* buf, int32_t size,
|
||||
|
@ -921,8 +939,12 @@ mime_image_stream_data::mime_image_stream_data() {
|
|||
}
|
||||
|
||||
static void* mime_image_begin(const char* image_url, const char* content_type,
|
||||
void* stream_closure) {
|
||||
mime_stream_data* msd = (mime_stream_data*)stream_closure;
|
||||
MimeClosure stream_closure) {
|
||||
PR_ASSERT(stream_closure.mType == MimeClosure::isMimeStreamData);
|
||||
if (stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return nullptr;
|
||||
}
|
||||
mime_stream_data* msd = (mime_stream_data*)stream_closure.mClosure;
|
||||
class mime_image_stream_data* mid;
|
||||
|
||||
mid = new mime_image_stream_data;
|
||||
|
@ -1140,14 +1162,14 @@ MimeDisplayOptions::MimeDisplayOptions() {
|
|||
default_charset = nullptr;
|
||||
override_charset = false;
|
||||
force_user_charset = false;
|
||||
stream_closure = nullptr;
|
||||
stream_closure = MimeClosure::zero();
|
||||
|
||||
/* For setting up the display stream, so that the MIME parser can inform
|
||||
the caller of the type of the data it will be getting. */
|
||||
output_init_fn = nullptr;
|
||||
output_fn = nullptr;
|
||||
|
||||
output_closure = nullptr;
|
||||
output_closure = MimeClosure::zero();
|
||||
|
||||
charset_conversion_fn = nullptr;
|
||||
rfc1522_conversion_p = false;
|
||||
|
@ -1377,7 +1399,8 @@ extern "C" void* mime_bridge_create_display_stream(
|
|||
msd->options->charset_conversion_fn = mime_convert_charset;
|
||||
msd->options->rfc1522_conversion_p = true;
|
||||
msd->options->file_type_fn = mime_file_type;
|
||||
msd->options->stream_closure = msd;
|
||||
msd->options->stream_closure =
|
||||
MimeClosure(MimeClosure::isMimeStreamData, msd);
|
||||
msd->options->passwd_prompt_fn = 0;
|
||||
|
||||
msd->options->image_begin = mime_image_begin;
|
||||
|
@ -1439,8 +1462,13 @@ extern "C" void* mime_bridge_create_display_stream(
|
|||
// Emitter Wrapper Routines!
|
||||
//
|
||||
nsIMimeEmitter* GetMimeEmitter(MimeDisplayOptions* opt) {
|
||||
mime_stream_data* msd = (mime_stream_data*)opt->stream_closure;
|
||||
if (!msd) return NULL;
|
||||
if (!opt->stream_closure) return NULL;
|
||||
|
||||
PR_ASSERT(opt->stream_closure.mType == MimeClosure::isMimeStreamData);
|
||||
if (opt->stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return nullptr;
|
||||
}
|
||||
mime_stream_data* msd = (mime_stream_data*)opt->stream_closure.mClosure;
|
||||
|
||||
nsIMimeEmitter* ptr = (nsIMimeEmitter*)(msd->output_emitter);
|
||||
return ptr;
|
||||
|
@ -1448,7 +1476,11 @@ nsIMimeEmitter* GetMimeEmitter(MimeDisplayOptions* opt) {
|
|||
|
||||
mime_stream_data* GetMSD(MimeDisplayOptions* opt) {
|
||||
if (!opt) return nullptr;
|
||||
mime_stream_data* msd = (mime_stream_data*)opt->stream_closure;
|
||||
PR_ASSERT(opt->stream_closure.mType == MimeClosure::isMimeStreamData);
|
||||
if (opt->stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return nullptr;
|
||||
}
|
||||
mime_stream_data* msd = (mime_stream_data*)opt->stream_closure.mClosure;
|
||||
return msd;
|
||||
}
|
||||
|
||||
|
@ -1718,10 +1750,17 @@ extern "C" char* MimeGetStringByName(const char16_t* stringName) {
|
|||
|
||||
void ResetChannelCharset(MimeObject* obj) {
|
||||
if (obj->options && obj->options->stream_closure &&
|
||||
obj->options->default_charset && obj->headers) {
|
||||
mime_stream_data* msd = (mime_stream_data*)(obj->options->stream_closure);
|
||||
obj->options->default_charset && obj->headers &&
|
||||
obj->options->stream_closure) {
|
||||
PR_ASSERT(obj->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData);
|
||||
if (obj->options->stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return;
|
||||
}
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(obj->options->stream_closure.mClosure);
|
||||
char* ct = MimeHeaders_get(obj->headers, HEADER_CONTENT_TYPE, false, false);
|
||||
if (ct && msd && msd->channel) {
|
||||
if (ct && msd->channel) {
|
||||
char* cSet = MimeHeaders_get_parameter(ct, "charset", nullptr, nullptr);
|
||||
if (cSet) {
|
||||
// The content-type does specify a charset. First, setup the channel.
|
||||
|
|
|
@ -686,7 +686,7 @@ static int MimeMultipartRelated_parse_child_line(MimeObject* obj,
|
|||
static int real_write(MimeMultipartRelated* relobj, const char* buf,
|
||||
int32_t size) {
|
||||
MimeObject* obj = (MimeObject*)relobj;
|
||||
void* closure = relobj->real_output_closure;
|
||||
MimeClosure closure = relobj->real_output_closure;
|
||||
|
||||
#ifdef MIME_DRAFTS
|
||||
if (obj->options && obj->options->decompose_file_p &&
|
||||
|
@ -697,10 +697,17 @@ static int real_write(MimeMultipartRelated* relobj, const char* buf,
|
|||
// then restore it when we are done. Not sure if we shouldn't just turn it
|
||||
// off permanently though.
|
||||
|
||||
mime_draft_data* mdd = (mime_draft_data*)obj->options->stream_closure;
|
||||
PR_ASSERT(obj->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeDraftData);
|
||||
if (obj->options->stream_closure.mType != MimeClosure::isMimeDraftData) {
|
||||
return -1;
|
||||
}
|
||||
mime_draft_data* mdd =
|
||||
(mime_draft_data*)obj->options->stream_closure.mClosure;
|
||||
MimeDecoderData* old_decoder_data = mdd->decoder_data;
|
||||
mdd->decoder_data = nullptr;
|
||||
int status = obj->options->decompose_file_output_fn(buf, size, (void*)mdd);
|
||||
int status = obj->options->decompose_file_output_fn(
|
||||
buf, size, MimeClosure(MimeClosure::isMimeDraftData, mdd));
|
||||
mdd->decoder_data = old_decoder_data;
|
||||
return status;
|
||||
} else
|
||||
|
@ -897,8 +904,12 @@ static int flush_tag(MimeMultipartRelated* relobj) {
|
|||
}
|
||||
|
||||
static int mime_multipart_related_output_fn(const char* buf, int32_t size,
|
||||
void* stream_closure) {
|
||||
MimeMultipartRelated* relobj = (MimeMultipartRelated*)stream_closure;
|
||||
MimeClosure stream_closure) {
|
||||
PR_ASSERT(stream_closure.mType == MimeClosure::isMimeMultipartRelated);
|
||||
if (stream_closure.mType != MimeClosure::isMimeMultipartRelated) {
|
||||
return -1;
|
||||
}
|
||||
MimeMultipartRelated* relobj = (MimeMultipartRelated*)stream_closure.mClosure;
|
||||
char* ptr;
|
||||
int32_t delta;
|
||||
int status;
|
||||
|
@ -963,7 +974,8 @@ static int MimeMultipartRelated_parse_eof(MimeObject* obj, bool abort_p) {
|
|||
relobj->real_output_closure = obj->options->output_closure;
|
||||
|
||||
obj->options->output_fn = mime_multipart_related_output_fn;
|
||||
obj->options->output_closure = obj;
|
||||
obj->options->output_closure =
|
||||
MimeClosure(MimeClosure::isMimeMultipartRelated, relobj);
|
||||
|
||||
body = mime_create(((ct && *ct) ? ct : (dct ? dct : TEXT_HTML)),
|
||||
relobj->buffered_hdrs, obj->options);
|
||||
|
@ -1022,8 +1034,9 @@ static int MimeMultipartRelated_parse_eof(MimeObject* obj, bool abort_p) {
|
|||
/* Read it out of memory. */
|
||||
PR_ASSERT(!relobj->file_buffer && !relobj->input_file_stream);
|
||||
|
||||
status = body->clazz->parse_buffer(relobj->head_buffer,
|
||||
relobj->head_buffer_fp, body);
|
||||
status =
|
||||
body->clazz->parse_buffer(relobj->head_buffer, relobj->head_buffer_fp,
|
||||
MimeClosure(MimeClosure::isMimeObject, body));
|
||||
} else if (relobj->file_buffer) {
|
||||
/* Read it off disk. */
|
||||
char* buf;
|
||||
|
@ -1064,7 +1077,8 @@ static int MimeMultipartRelated_parse_eof(MimeObject* obj, bool abort_p) {
|
|||
some user events and other input sources get processed.
|
||||
Oh well. */
|
||||
|
||||
status = body->clazz->parse_buffer(buf, bytesRead, body);
|
||||
status = body->clazz->parse_buffer(
|
||||
buf, bytesRead, MimeClosure(MimeClosure::isMimeObject, body));
|
||||
if (status < 0) break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ struct MimeMultipartRelated {
|
|||
PLHashTable* hash;
|
||||
|
||||
MimeConverterOutputCallback real_output_fn;
|
||||
void* real_output_closure;
|
||||
MimeClosure real_output_closure;
|
||||
|
||||
char* curtag;
|
||||
int32_t curtag_max;
|
||||
|
@ -56,6 +56,6 @@ struct MimeMultipartRelated {
|
|||
};
|
||||
|
||||
#define MimeMultipartRelatedClassInitializer(ITYPE, CSUPER) \
|
||||
{ MimeMultipartClassInitializer(ITYPE, CSUPER) }
|
||||
{MimeMultipartClassInitializer(ITYPE, CSUPER)}
|
||||
|
||||
#endif /* _MIMEMREL_H_ */
|
||||
|
|
|
@ -171,14 +171,17 @@ static int MimeMessage_parse_line(const char* aLine, int32_t aLength,
|
|||
#endif /* MIME_DRAFTS */
|
||||
|
||||
if (nl)
|
||||
return kid->clazz->parse_buffer(line, length, kid);
|
||||
return kid->clazz->parse_buffer(
|
||||
line, length, MimeClosure(MimeClosure::isMimeObject, kid));
|
||||
else {
|
||||
/* Hack a newline onto the end. */
|
||||
char* s = (char*)PR_MALLOC(length + MSG_LINEBREAK_LEN + 1);
|
||||
if (!s) return MIME_OUT_OF_MEMORY;
|
||||
memcpy(s, line, length);
|
||||
PL_strncpyz(s + length, MSG_LINEBREAK, MSG_LINEBREAK_LEN + 1);
|
||||
status = kid->clazz->parse_buffer(s, length + MSG_LINEBREAK_LEN, kid);
|
||||
status =
|
||||
kid->clazz->parse_buffer(s, length + MSG_LINEBREAK_LEN,
|
||||
MimeClosure(MimeClosure::isMimeObject, kid));
|
||||
PR_Free(s);
|
||||
return status;
|
||||
}
|
||||
|
@ -505,8 +508,15 @@ static int MimeMessage_parse_eof(MimeObject* obj, bool abort_p) {
|
|||
if ((outer_p || obj->options->notify_nested_bodies) && obj->options &&
|
||||
obj->options->write_html_p) {
|
||||
if (obj->options->generate_footer_html_fn) {
|
||||
mime_stream_data* msd = (mime_stream_data*)obj->options->stream_closure;
|
||||
if (msd) {
|
||||
if (obj->options->stream_closure) {
|
||||
PR_ASSERT(obj->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData);
|
||||
if (obj->options->stream_closure.mType !=
|
||||
MimeClosure::isMimeStreamData) {
|
||||
return 0;
|
||||
}
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)obj->options->stream_closure.mClosure;
|
||||
char* html = obj->options->generate_footer_html_fn(
|
||||
msd->orig_url_name, obj->options->html_closure, msg->hdrs);
|
||||
if (html) {
|
||||
|
|
|
@ -85,7 +85,7 @@ static void MimeMultipartSigned_cleanup(MimeObject* obj, bool finalizing_p) {
|
|||
around for the lifetime of the MIME object, so that we can get at the
|
||||
security info of sub-parts of the currently-displayed message. */
|
||||
((MimeMultipartSignedClass*)obj->clazz)->crypto_free(sig->crypto_closure);
|
||||
sig->crypto_closure = 0;
|
||||
sig->crypto_closure = MimeClosure::zero();
|
||||
}
|
||||
|
||||
if (sig->sig_decoder_data) {
|
||||
|
@ -329,7 +329,7 @@ static int MimeMultipartSigned_parse_line(const char* line, int32_t length,
|
|||
(Similar logic is in MimeLeafClass->parse_begin.)
|
||||
*/
|
||||
{
|
||||
MimeDecoderData* (*fn)(MimeConverterOutputCallback, void*) = 0;
|
||||
MimeDecoderData* (*fn)(MimeConverterOutputCallback, MimeClosure) = 0;
|
||||
nsCString encoding;
|
||||
encoding.Adopt(MimeHeaders_get(
|
||||
sig->sig_hdrs, HEADER_CONTENT_TRANSFER_ENCODING, true, false));
|
||||
|
@ -339,9 +339,7 @@ static int MimeMultipartSigned_parse_line(const char* line, int32_t length,
|
|||
fn = &MimeB64DecoderInit;
|
||||
else if (!PL_strcasecmp(encoding.get(), ENCODING_QUOTED_PRINTABLE)) {
|
||||
sig->sig_decoder_data = MimeQPDecoderInit(
|
||||
((MimeConverterOutputCallback)(((MimeMultipartSignedClass*)
|
||||
obj->clazz)
|
||||
->crypto_signature_hash)),
|
||||
(((MimeMultipartSignedClass*)obj->clazz)->crypto_signature_hash),
|
||||
sig->crypto_closure);
|
||||
if (!sig->sig_decoder_data) return MIME_OUT_OF_MEMORY;
|
||||
} else if (!PL_strcasecmp(encoding.get(), ENCODING_UUENCODE) ||
|
||||
|
@ -352,11 +350,9 @@ static int MimeMultipartSigned_parse_line(const char* line, int32_t length,
|
|||
else if (!PL_strcasecmp(encoding.get(), ENCODING_YENCODE))
|
||||
fn = &MimeYDecoderInit;
|
||||
if (fn) {
|
||||
sig->sig_decoder_data =
|
||||
fn(((MimeConverterOutputCallback)(((MimeMultipartSignedClass*)
|
||||
obj->clazz)
|
||||
->crypto_signature_hash)),
|
||||
sig->crypto_closure);
|
||||
sig->sig_decoder_data = fn(
|
||||
(((MimeMultipartSignedClass*)obj->clazz)->crypto_signature_hash),
|
||||
sig->crypto_closure);
|
||||
if (!sig->sig_decoder_data) return MIME_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -701,21 +697,15 @@ static int MimeMultipartSigned_emit_child(MimeObject* obj) {
|
|||
if (body->options->decompose_file_p &&
|
||||
!mime_typep(body, (MimeObjectClass*)&mimeMultipartClass) &&
|
||||
body->options->decompose_file_output_fn)
|
||||
status =
|
||||
MimePartBufferRead(sig->part_buffer,
|
||||
/* The (MimeConverterOutputCallback) cast is to
|
||||
turn the `void' argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)
|
||||
body->options->decompose_file_output_fn),
|
||||
body->options->stream_closure);
|
||||
status = MimePartBufferRead(sig->part_buffer,
|
||||
|
||||
body->options->decompose_file_output_fn,
|
||||
body->options->stream_closure);
|
||||
else
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
||||
status = MimePartBufferRead(
|
||||
sig->part_buffer,
|
||||
/* The (MimeConverterOutputCallback) cast is to turn the
|
||||
`void' argument into `MimeObject'. */
|
||||
((MimeConverterOutputCallback)body->clazz->parse_buffer), body);
|
||||
status = MimePartBufferRead(sig->part_buffer, body->clazz->parse_buffer,
|
||||
MimeClosure(MimeClosure::isMimeObject, body));
|
||||
if (status < 0) return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,27 +93,27 @@ struct MimeMultipartSignedClass {
|
|||
MimeMultipartClass multipart;
|
||||
|
||||
/* Callbacks used by dexlateion (really, signature verification) module. */
|
||||
void* (*crypto_init)(MimeObject* multipart_object);
|
||||
MimeClosure (*crypto_init)(MimeObject* multipart_object);
|
||||
|
||||
int (*crypto_data_hash)(const char* data, int32_t data_size,
|
||||
void* crypto_closure);
|
||||
MimeClosure crypto_closure);
|
||||
int (*crypto_signature_hash)(const char* data, int32_t data_size,
|
||||
void* crypto_closure);
|
||||
MimeClosure crypto_closure);
|
||||
|
||||
int (*crypto_data_eof)(void* crypto_closure, bool abort_p);
|
||||
int (*crypto_signature_eof)(void* crypto_closure, bool abort_p);
|
||||
int (*crypto_data_eof)(MimeClosure crypto_closure, bool abort_p);
|
||||
int (*crypto_signature_eof)(MimeClosure crypto_closure, bool abort_p);
|
||||
|
||||
int (*crypto_signature_init)(void* crypto_closure,
|
||||
int (*crypto_signature_init)(MimeClosure crypto_closure,
|
||||
MimeObject* multipart_object,
|
||||
MimeHeaders* signature_hdrs);
|
||||
|
||||
int (*crypto_signature_ignore)(void* crypto_closure);
|
||||
int (*crypto_signature_ignore)(MimeClosure crypto_closure);
|
||||
|
||||
char* (*crypto_generate_html)(void* crypto_closure);
|
||||
char* (*crypto_generate_html)(MimeClosure crypto_closure);
|
||||
|
||||
void (*crypto_notify_suppressed_child)(void* crypto_closure);
|
||||
void (*crypto_notify_suppressed_child)(MimeClosure crypto_closure);
|
||||
|
||||
void (*crypto_free)(void* crypto_closure);
|
||||
void (*crypto_free)(MimeClosure crypto_closure);
|
||||
};
|
||||
|
||||
extern "C" MimeMultipartSignedClass mimeMultipartSignedClass;
|
||||
|
@ -122,7 +122,7 @@ struct MimeMultipartSigned {
|
|||
MimeMultipart multipart;
|
||||
MimeMultipartSignedParseState state; /* State of parser */
|
||||
|
||||
void* crypto_closure; /* Opaque data used by signature
|
||||
MimeClosure crypto_closure; /* Opaque data used by signature
|
||||
verification module. */
|
||||
|
||||
MimeHeaders* body_hdrs; /* The headers of the signed object. */
|
||||
|
|
|
@ -462,11 +462,18 @@ static int MimeMultipart_create_child(MimeObject* obj) {
|
|||
/* if we are saving an apple double attachment, we need to set correctly the
|
||||
* content type of the channel */
|
||||
if (mime_typep(obj, (MimeObjectClass*)&mimeMultipartAppleDoubleClass)) {
|
||||
mime_stream_data* msd = (mime_stream_data*)body->options->stream_closure;
|
||||
if (!body->options->write_html_p && body->content_type &&
|
||||
!PL_strcasecmp(body->content_type, APPLICATION_APPLEFILE)) {
|
||||
if (msd && msd->channel)
|
||||
msd->channel->SetContentType(nsLiteralCString(APPLICATION_APPLEFILE));
|
||||
PR_ASSERT(body->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData);
|
||||
if (body->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData) {
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)body->options->stream_closure.mClosure;
|
||||
if (!body->options->write_html_p && body->content_type &&
|
||||
!PL_strcasecmp(body->content_type, APPLICATION_APPLEFILE)) {
|
||||
if (msd && msd->channel)
|
||||
msd->channel->SetContentType(
|
||||
nsLiteralCString(APPLICATION_APPLEFILE));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -598,12 +605,14 @@ static int MimeMultipart_parse_child_line(MimeObject* obj, const char* line,
|
|||
if (!first_line_p) {
|
||||
/* Push out a preceding newline... */
|
||||
char nl[] = MSG_LINEBREAK;
|
||||
status = kid->clazz->parse_buffer(nl, MSG_LINEBREAK_LEN, kid);
|
||||
status = kid->clazz->parse_buffer(
|
||||
nl, MSG_LINEBREAK_LEN, MimeClosure(MimeClosure::isMimeObject, kid));
|
||||
if (status < 0) return status;
|
||||
}
|
||||
|
||||
/* Now push out the line sans trailing newline. */
|
||||
return kid->clazz->parse_buffer(line, length, kid);
|
||||
return kid->clazz->parse_buffer(line, length,
|
||||
MimeClosure(MimeClosure::isMimeObject, kid));
|
||||
}
|
||||
|
||||
static int MimeMultipart_parse_eof(MimeObject* obj, bool abort_p) {
|
||||
|
|
|
@ -28,7 +28,7 @@ MimeDefClass(MimeObject, MimeObjectClass, mimeObjectClass, NULL);
|
|||
static int MimeObject_initialize(MimeObject*);
|
||||
static void MimeObject_finalize(MimeObject*);
|
||||
static int MimeObject_parse_begin(MimeObject*);
|
||||
static int MimeObject_parse_buffer(const char*, int32_t, MimeObject*);
|
||||
static int MimeObject_parse_buffer(const char*, int32_t, MimeClosure);
|
||||
static int MimeObject_parse_line(const char*, int32_t, MimeObject*);
|
||||
static int MimeObject_parse_eof(MimeObject*, bool);
|
||||
static int MimeObject_parse_end(MimeObject*, bool);
|
||||
|
@ -210,7 +210,13 @@ static int MimeObject_parse_begin(MimeObject* obj) {
|
|||
}
|
||||
|
||||
static int MimeObject_parse_buffer(const char* buffer, int32_t size,
|
||||
MimeObject* obj) {
|
||||
MimeClosure closure) {
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeObject);
|
||||
if (closure.mType != MimeClosure::isMimeObject) {
|
||||
return -1;
|
||||
}
|
||||
MimeObject* obj = (MimeObject*)closure.mClosure;
|
||||
|
||||
NS_ASSERTION(!obj->closed_p, "object shouldn't be closed");
|
||||
if (obj->closed_p) return -1;
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ struct MimeObjectClass {
|
|||
int (*initialize)(MimeObject* obj);
|
||||
void (*finalize)(MimeObject* obj);
|
||||
int (*parse_begin)(MimeObject* obj);
|
||||
int (*parse_buffer)(const char* buf, int32_t size, MimeObject* obj);
|
||||
int (*parse_buffer)(const char* buf, int32_t size, MimeClosure closure);
|
||||
int (*parse_line)(const char* line, int32_t length, MimeObject* obj);
|
||||
int (*parse_eof)(MimeObject* obj, bool abort_p);
|
||||
int (*parse_end)(MimeObject* obj, bool abort_p);
|
||||
|
|
|
@ -197,7 +197,8 @@ int MimePartBufferWrite(MimePartBufferData* data, const char* buf,
|
|||
}
|
||||
|
||||
int MimePartBufferRead(MimePartBufferData* data,
|
||||
MimeConverterOutputCallback read_fn, void* closure) {
|
||||
MimeConverterOutputCallback read_fn,
|
||||
MimeClosure closure) {
|
||||
int status = 0;
|
||||
NS_ASSERTION(data, "no data");
|
||||
if (!data) return -1;
|
||||
|
|
|
@ -57,6 +57,6 @@ extern int MimePartBufferWrite(MimePartBufferData* data, const char* buf,
|
|||
*/
|
||||
extern int MimePartBufferRead(MimePartBufferData* data,
|
||||
MimeConverterOutputCallback read_fn,
|
||||
void* closure);
|
||||
MimeClosure closure);
|
||||
|
||||
#endif /* _MIMEPBUF_H_ */
|
||||
|
|
|
@ -310,5 +310,6 @@ static int MimeSunAttachment_parse_child_line(MimeObject* obj, const char* line,
|
|||
PR_ASSERT(kid);
|
||||
if (!kid) return -1;
|
||||
|
||||
return kid->clazz->parse_buffer(line, length, kid);
|
||||
return kid->clazz->parse_buffer(line, length,
|
||||
MimeClosure(MimeClosure::isMimeObject, kid));
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ static int MimeInlineText_rot13_line(MimeObject*, char* line, int32_t length);
|
|||
static int MimeInlineText_parse_eof(MimeObject* obj, bool abort_p);
|
||||
static int MimeInlineText_parse_end(MimeObject*, bool);
|
||||
static int MimeInlineText_parse_decoded_buffer(const char*, int32_t,
|
||||
MimeObject*);
|
||||
MimeClosure);
|
||||
static int MimeInlineText_rotate_convert_and_parse_line(const char*, int32_t,
|
||||
MimeObject*);
|
||||
static int MimeInlineText_open_dam(const char* line, int32_t length,
|
||||
|
@ -249,7 +249,13 @@ static int MimeInlineText_rot13_line(MimeObject* obj, char* line,
|
|||
}
|
||||
|
||||
static int MimeInlineText_parse_decoded_buffer(const char* buf, int32_t size,
|
||||
MimeObject* obj) {
|
||||
MimeClosure closure) {
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeObject);
|
||||
if (closure.mType != MimeClosure::isMimeObject) {
|
||||
return -1;
|
||||
}
|
||||
MimeObject* obj = (MimeObject*)closure.mClosure;
|
||||
|
||||
PR_ASSERT(!obj->closed_p);
|
||||
if (obj->closed_p) return -1;
|
||||
|
||||
|
|
|
@ -146,8 +146,8 @@ static int MimeUntypedText_parse_line(const char* line, int32_t length,
|
|||
|
||||
/* Hand this line to the currently-open sub-part.
|
||||
*/
|
||||
status =
|
||||
uty->open_subpart->clazz->parse_buffer(line, length, uty->open_subpart);
|
||||
status = uty->open_subpart->clazz->parse_buffer(
|
||||
line, length, MimeClosure(MimeClosure::isMimeObject, uty->open_subpart));
|
||||
if (status < 0) return status;
|
||||
|
||||
/* Close this sub-part if this line demands it.
|
||||
|
|
|
@ -198,20 +198,20 @@ class MimeDisplayOptions {
|
|||
is what is found in `options->stream_closure'. (One possible exception
|
||||
is for output_fn; see "output_closure" below.)
|
||||
*/
|
||||
void* stream_closure;
|
||||
MimeClosure stream_closure;
|
||||
|
||||
/* For setting up the display stream, so that the MIME parser can inform
|
||||
the caller of the type of the data it will be getting. */
|
||||
int (*output_init_fn)(const char* type, const char* charset, const char* name,
|
||||
const char* x_mac_type, const char* x_mac_creator,
|
||||
void* stream_closure);
|
||||
MimeClosure stream_closure);
|
||||
|
||||
/* How the MIME parser feeds its output (HTML or raw) back to the caller. */
|
||||
MimeConverterOutputCallback output_fn;
|
||||
|
||||
/* Closure to pass to the above output_fn. If NULL, then the
|
||||
stream_closure is used. */
|
||||
void* output_closure;
|
||||
MimeClosure output_closure;
|
||||
|
||||
/* A hook for the caller to perform charset-conversion before HTML is
|
||||
returned. Each set of characters which originated in a mail message
|
||||
|
@ -232,7 +232,8 @@ class MimeDisplayOptions {
|
|||
*/
|
||||
int (*charset_conversion_fn)(const char* input_line, int32_t input_length,
|
||||
const char* input_charset,
|
||||
nsACString& output_ret, void* stream_closure);
|
||||
nsACString& output_ret,
|
||||
MimeClosure stream_closure);
|
||||
|
||||
/* If true, perform both charset-conversion and decoding of
|
||||
MIME-2 header fields (using RFC-1522 encoding.)
|
||||
|
@ -240,7 +241,7 @@ class MimeDisplayOptions {
|
|||
bool rfc1522_conversion_p;
|
||||
|
||||
/* A hook for the caller to turn a file name into a content-type. */
|
||||
char* (*file_type_fn)(const char* filename, void* stream_closure);
|
||||
char* (*file_type_fn)(const char* filename, MimeClosure stream_closure);
|
||||
|
||||
/* A hook by which the user may be prompted for a password by the security
|
||||
library. (This is really of type `SECKEYGetPasswordKey'; see sec.h.) */
|
||||
|
@ -283,7 +284,7 @@ class MimeDisplayOptions {
|
|||
/* Begins processing an embedded image; the URL and content_type are of the
|
||||
image itself. */
|
||||
void* (*image_begin)(const char* image_url, const char* content_type,
|
||||
void* stream_closure);
|
||||
MimeClosure stream_closure);
|
||||
|
||||
/* Stop processing an image. */
|
||||
void (*image_end)(void* image_closure, int status);
|
||||
|
@ -325,14 +326,15 @@ class MimeDisplayOptions {
|
|||
/* Callback to gather the outer most headers so we could use the
|
||||
information to initialize the addressing/subject/newsgroups fields
|
||||
for the composition window. */
|
||||
int (*decompose_headers_info_fn)(void* closure, MimeHeaders* headers);
|
||||
int (*decompose_headers_info_fn)(MimeClosure closure, MimeHeaders* headers);
|
||||
|
||||
/* Callbacks to create temporary files for drafts attachments. */
|
||||
int (*decompose_file_init_fn)(void* stream_closure, MimeHeaders* headers);
|
||||
int (*decompose_file_init_fn)(MimeClosure stream_closure,
|
||||
MimeHeaders* headers);
|
||||
|
||||
MimeConverterOutputCallback decompose_file_output_fn;
|
||||
|
||||
int (*decompose_file_close_fn)(void* stream_closure);
|
||||
int (*decompose_file_close_fn)(MimeClosure stream_closure);
|
||||
#endif /* MIME_DRAFTS */
|
||||
|
||||
int32_t attachment_icon_layer_id; /* Hackhackhack. This is zero if we have
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
#define _MIMEENC_H_
|
||||
|
||||
#include "nscore.h" // for nullptr
|
||||
#include "mime_closure.h"
|
||||
|
||||
typedef int (*MimeConverterOutputCallback)(const char* buf, int32_t size,
|
||||
void* closure);
|
||||
MimeClosure closure);
|
||||
|
||||
/* This file defines interfaces to generic implementations of Base64,
|
||||
Quoted-Printable, and UU decoders; and of Base64 and Quoted-Printable
|
||||
|
@ -29,15 +30,16 @@ struct MimeObject;
|
|||
/* functions for creating that opaque data.
|
||||
*/
|
||||
MimeDecoderData* MimeB64DecoderInit(MimeConverterOutputCallback output_fn,
|
||||
void* closure);
|
||||
MimeClosure closure);
|
||||
|
||||
MimeDecoderData* MimeQPDecoderInit(MimeConverterOutputCallback output_fn,
|
||||
void* closure, MimeObject* object = nullptr);
|
||||
MimeClosure closure,
|
||||
MimeObject* object = nullptr);
|
||||
|
||||
MimeDecoderData* MimeUUDecoderInit(MimeConverterOutputCallback output_fn,
|
||||
void* closure);
|
||||
MimeClosure closure);
|
||||
MimeDecoderData* MimeYDecoderInit(MimeConverterOutputCallback output_fn,
|
||||
void* closure);
|
||||
MimeClosure closure);
|
||||
|
||||
/* Push data through the encoder/decoder, causing the above-provided write_fn
|
||||
to be called with encoded/decoded data. */
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS += [
|
||||
"mime_closure.h",
|
||||
"mimecont.h",
|
||||
"mimecryp.h",
|
||||
"mimecth.h",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "prlog.h"
|
||||
#include "mimecth.h"
|
||||
#include "mimetext.h"
|
||||
#include "mimemoz2.h"
|
||||
|
@ -73,7 +74,14 @@ static int EndGather(MimeObject* obj, bool abort_p) {
|
|||
|
||||
if (ssobj->buffer->IsEmpty()) return 0;
|
||||
|
||||
mime_stream_data* msd = (mime_stream_data*)(obj->options->stream_closure);
|
||||
PR_ASSERT(obj->options->stream_closure.mType ==
|
||||
MimeClosure::isMimeStreamData);
|
||||
if (obj->options->stream_closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mime_stream_data* msd =
|
||||
(mime_stream_data*)(obj->options->stream_closure.mClosure);
|
||||
nsIChannel* channel = msd->channel; // note the lack of ref counting...
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
|
|
|
@ -142,12 +142,17 @@ nsresult bridge_new_new_uri(void* bridgeStream, nsIURI* aURI,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static int mime_headers_callback(void* closure, MimeHeaders* headers) {
|
||||
// We get away with this because this doesn't get called on draft operations.
|
||||
mime_stream_data* msd = (mime_stream_data*)closure;
|
||||
static int mime_headers_callback(MimeClosure closure, MimeHeaders* headers) {
|
||||
NS_ASSERTION(closure && headers, "null mime stream data or headers");
|
||||
if (!closure || !headers) return 0;
|
||||
|
||||
NS_ASSERTION(msd && headers, "null mime stream data or headers");
|
||||
if (!msd || !headers) return 0;
|
||||
// We get away with this because this doesn't get called on draft operations.
|
||||
PR_ASSERT(closure.mType == MimeClosure::isMimeStreamData);
|
||||
if (closure.mType != MimeClosure::isMimeStreamData) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
mime_stream_data* msd = (mime_stream_data*)closure.mClosure;
|
||||
|
||||
NS_ASSERTION(!msd->headers, "non-null mime stream data headers");
|
||||
msd->headers = MimeHeaders_copy(headers);
|
||||
|
|
Загрузка…
Ссылка в новой задаче