jstedfast / gmime

A C/C++ MIME creation and parser library with support for S/MIME, PGP, and Unix mbox spools.
GNU Lesser General Public License v2.1
111 stars 36 forks source link

Can't copy message from stream to a buffer #163

Closed tengliu0929 closed 2 months ago

tengliu0929 commented 2 months ago

Need help, I have tried decode base64 from a GMimeStream to a memory GMimeStream, the code snippet is below

GMimeDataWrapper *datawrapper = g_mime_part_get_content_object(part);
GMimeStream *datastream = g_mime_data_wrapper_get_stream(datawrapper);
GMimeStream *filteredstream = g_mime_stream_filter_new(datastream);
GMimeFilter *filter_base64 = g_mime_filter_basic_new(GMIME_CONTENT_ENCODING_BASE64,false);

g_mime_stream_filter_add(GMIME_STREAM_FILTER(filteredstream),filter_base64);
//GMimeFilter *filter_charset = g_mime_filter_charset_new(charset,g_mime_charset_locale_name());
//g_mime_stream_filter_add((GMimeStreamFilter *)filteredstream,filter_charset);
//GMimeStream *out = g_mime_stream_file_new(stdout);
//int outlen = g_mime_stream_write_to_stream(filteredstream,out);

GMimeStream *out_mem = g_mime_stream_mem_new();
int b_len = g_mime_stream_write_to_stream(filteredstream,out_mem);

g_mime_stream_flush(filteredstream);

GByteArray *bytearray = GMIME_STREAM_MEM(out_mem)->buffer;

printf("b_len --> %d\n",b_len);

char buf[4096] = {0};
int buf_len = 0;

buf_len = g_mime_stream_read(out_mem,buf,4096);
printf("buf_len --> %d\n",buf_len);

I can't read any message from the out_mem stream, buf the bytearray shows the decoded message does exist. and I debug into the function stream_read, the error occur in here

bound_end = stream->bound_end != -1 ? stream->bound_end : (gint64) mem->buffer->len; n = (size_t) MIN (bound_end - stream->position, (gint64) len); I print the out_mem using gdb, {parent_object = {g_type_instance = {g_class = 0x625790}, ref_count = 1, qdata = 0x0}, super_stream = 0x0, position = 351, bound_start = 0, bound_end = -1} Does there is any bugs or I use the functions in the wrong way ? Besides, the gmime version is 2.6.23. Thanks a lot.

jstedfast commented 2 months ago

A few points:

  1. Remove the call to g_mime_stream_flush(filteredstream); - only call flush() on the output stream, never the input stream. I doubt it's doing any harm in your particular case, but it's bad practice.
  2. Before reading from out_mem, make sure to reset it using g_mime_stream_reset(out_mem);