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:
Kai Engert 2024-09-17 10:17:56 +02:00
Родитель 84fc0b8087
Коммит 30ce1a27b4
36 изменённых файлов: 701 добавлений и 426 удалений

Просмотреть файл

@ -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);