From 7202b59cbb034280dcceada6044d251179b6d0c1 Mon Sep 17 00:00:00 2001 From: Tarashish Mishra Date: Thu, 13 Sep 2018 13:28:11 +0530 Subject: [PATCH] Add method to get attachment name --- libpff/libpff_attachment.c | 95 ++++++++++++++++++++++++++++ libpff/libpff_attachment.h | 13 ++++ pypff/pypff_attachment.c | 125 +++++++++++++++++++++++++++++++++++++ pypff/pypff_attachment.h | 4 ++ 4 files changed, 237 insertions(+) diff --git a/libpff/libpff_attachment.c b/libpff/libpff_attachment.c index 7bb84804..7767f891 100644 --- a/libpff/libpff_attachment.c +++ b/libpff/libpff_attachment.c @@ -1130,3 +1130,98 @@ int libpff_attachment_get_item( return( -1 ); } +/* Retrieves the size of the UTF-8 encoded name + * The size includes the end of string character + * Returns 1 if successful, 0 if value is not available or -1 on error + */ +int libpff_attachment_get_utf8_name_size( + libpff_item_t *attachment, + size_t *utf8_string_size, + libcerror_error_t **error) +{ + libpff_internal_item_t *internal_item = NULL; + static char *function = "libpff_attachment_get_utf8_name_size"; + int result = 0; + + if (attachment == NULL) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid attachment.", + function); + + return (-1); + } + internal_item = (libpff_internal_item_t *)attachment; + + result = libpff_internal_item_get_entry_value_utf8_string_size( + internal_item, + LIBPFF_ENTRY_TYPE_ATTACHMENT_FILENAME_LONG, + internal_item->ascii_codepage, + utf8_string_size, + error); + + if (result == -1) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve size of name as UTF-8 string.", + function); + + return (-1); + } + return (result); +} + +/* Retrieves the UTF-8 encoded name + * The size should include the end of string character + * Returns 1 if successful, 0 if value is not available or -1 on error + */ +int libpff_attachment_get_utf8_name( + libpff_item_t *attachment, + uint8_t *utf8_string, + size_t utf8_string_size, + libcerror_error_t **error) +{ + libpff_internal_item_t *internal_item = NULL; + static char *function = "libpff_attachment_get_utf8_name"; + int result = 0; + + if (attachment == NULL) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid attachment.", + function); + + return (-1); + } + internal_item = (libpff_internal_item_t *)attachment; + + result = libpff_internal_item_get_entry_value_utf8_string( + internal_item, + LIBPFF_ENTRY_TYPE_ATTACHMENT_FILENAME_LONG, + internal_item->ascii_codepage, + utf8_string, + utf8_string_size, + error); + + if (result == -1) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve name as UTF-8 string.", + function); + + return (-1); + } + return (result); +} diff --git a/libpff/libpff_attachment.h b/libpff/libpff_attachment.h index b657c5e1..abe4af85 100644 --- a/libpff/libpff_attachment.h +++ b/libpff/libpff_attachment.h @@ -41,6 +41,19 @@ int libpff_attachment_get_type( int *attachment_type, libcerror_error_t **error ); +LIBPFF_EXTERN +int libpff_attachment_get_utf8_name_size( + libpff_item_t *attachment, + size_t *utf8_string_size, + libcerror_error_t **error); + +LIBPFF_EXTERN +int libpff_attachment_get_utf8_name( + libpff_item_t *attachment, + uint8_t *utf8_string, + size_t utf8_string_size, + libcerror_error_t **error); + LIBPFF_EXTERN \ int libpff_attachment_get_data_size( libpff_item_t *attachment, diff --git a/pypff/pypff_attachment.c b/pypff/pypff_attachment.c index c1f89224..7ec0c625 100644 --- a/pypff/pypff_attachment.c +++ b/pypff/pypff_attachment.c @@ -46,6 +46,13 @@ PyMethodDef pypff_attachment_object_methods[] = { "\n" "Retrieves the attachment data size." }, + { "get_name", + (PyCFunction) pypff_attachment_get_name, + METH_NOARGS, + "get_name() -> Unicode string or None\n" + "\n" + "Retrieves the name." }, + { "read_buffer", (PyCFunction) pypff_attachment_read_buffer, METH_VARARGS | METH_KEYWORDS, @@ -72,6 +79,12 @@ PyGetSetDef pypff_attachment_object_get_set_definitions[] = { "The data size.", NULL }, + { "name", + (getter) pypff_attachment_get_name, + (setter) 0, + "The name.", + NULL }, + /* Sentinel */ { NULL, NULL, NULL, NULL, NULL } }; @@ -400,3 +413,115 @@ PyObject *pypff_attachment_seek_offset( return( Py_None ); } +/* Retrieves the name + * Returns a Python object if successful or NULL on error + */ +PyObject *pypff_attachment_get_name( + pypff_item_t *pypff_item, + PyObject *arguments PYPFF_ATTRIBUTE_UNUSED) +{ + PyObject *string_object = NULL; + libcerror_error_t *error = NULL; + uint8_t *utf8_string = NULL; + const char *errors = NULL; + static char *function = "pypff_attachment_get_name"; + size_t utf8_string_size = 0; + int result = 0; + + PYPFF_UNREFERENCED_PARAMETER(arguments) + + if (pypff_item == NULL) + { + PyErr_Format( + PyExc_TypeError, + "%s: invalid item.", + function); + + return (NULL); + } + Py_BEGIN_ALLOW_THREADS + + result = libpff_attachment_get_utf8_name_size( + pypff_item->item, + &utf8_string_size, + &error); + + Py_END_ALLOW_THREADS + + if (result == -1) + { + pypff_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve size of UTF-8 name.", + function); + + libcerror_error_free( + &error); + + goto on_error; + } + else if ((result == 0) || (utf8_string_size == 0)) + { + Py_IncRef( + Py_None); + + return (Py_None); + } + utf8_string = (uint8_t *)PyMem_Malloc( + sizeof(uint8_t) * utf8_string_size); + + if (utf8_string == NULL) + { + PyErr_Format( + PyExc_IOError, + "%s: unable to create name.", + function); + + goto on_error; + } + Py_BEGIN_ALLOW_THREADS + + result = libpff_attachment_get_utf8_name( + pypff_item->item, + utf8_string, + utf8_string_size, + &error); + + Py_END_ALLOW_THREADS + + if (result != 1) + { + pypff_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve UTF-8 name.", + function); + + libcerror_error_free( + &error); + + goto on_error; + } + /* Pass the string length to PyUnicode_DecodeUTF8 + * otherwise it makes the end of string character is part + * of the string + */ + string_object = PyUnicode_DecodeUTF8( + (char *)utf8_string, + (Py_ssize_t)utf8_string_size - 1, + errors); + + PyMem_Free( + utf8_string); + + return (string_object); + +on_error: + if (utf8_string != NULL) + { + PyMem_Free( + utf8_string); + } + return (NULL); +} \ No newline at end of file diff --git a/pypff/pypff_attachment.h b/pypff/pypff_attachment.h index f7158b58..fec67216 100644 --- a/pypff/pypff_attachment.h +++ b/pypff/pypff_attachment.h @@ -39,6 +39,10 @@ PyObject *pypff_attachment_get_size( pypff_item_t *pypff_item, PyObject *arguments ); +PyObject *pypff_attachment_get_name( + pypff_item_t *pypff_item, + PyObject *arguments); + PyObject *pypff_attachment_read_buffer( pypff_item_t *pypff_item, PyObject *arguments,