summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/common/leb128.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/common/leb128.c')
-rw-r--r--plugins/pychrysalide/common/leb128.c139
1 files changed, 77 insertions, 62 deletions
diff --git a/plugins/pychrysalide/common/leb128.c b/plugins/pychrysalide/common/leb128.c
index 8b15303..2eeb191 100644
--- a/plugins/pychrysalide/common/leb128.c
+++ b/plugins/pychrysalide/common/leb128.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* leb128.c - équivalent Python du fichier "common/leb128.c"
*
- * Copyright (C) 2018-2020 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -26,13 +26,13 @@
#include <assert.h>
+#include <malloc.h>
#include <pygobject.h>
#include <common/leb128.h>
-#include "packed.h"
#include "../access.h"
#include "../helpers.h"
@@ -69,31 +69,29 @@ static PyObject *py_leb128_pack_uleb128(PyObject *self, PyObject *args)
{
PyObject *result; /* Valeur à retourner */
uleb128_t value; /* Valeur à manipuler */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
int ret; /* Bilan de lecture des args. */
- bool status; /* Bilan de l'opération */
-
-#define LEB128_PACK_ULEB128_METHOD PYTHON_METHOD_DEF \
-( \
- pack_uleb128, "value, pbuf", \
- METH_VARARGS, py_leb128, \
- "Pack an unsigned LEB128 value into a data buffer.\n" \
- "\n" \
- "The *value* is an integer value. The *pbuf* argument has to" \
- " be a pychrysalide.common.PackedBuffer instance where data" \
- " will be appended.\n" \
- "\n" \
- "The returned value is the operation status: *True* for" \
- " success, *False* for failure." \
+ size_t count; /* Nombre d'octets produits */
+ void *bytes; /* Octets de représentation */
+
+#define LEB128_PACK_ULEB128_METHOD PYTHON_METHOD_DEF \
+( \
+ pack_uleb128, "value", \
+ METH_VARARGS, py_leb128, \
+ "Pack an unsigned LEB128 value into bytes.\n" \
+ "\n" \
+ "The *value* has to be an integer value.\n" \
+ "\n" \
+ "The returned value is byte data." \
)
- ret = PyArg_ParseTuple(args, "O&O&", convert_to_uleb128_value, &value, convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "O&", convert_to_uleb128_value, &value);
if (!ret) return NULL;
- status = pack_uleb128(&value, pbuf);
+ bytes = pack_uleb128(&value, &count);
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
+ result = PyBytes_FromStringAndSize(bytes, count);
+
+ free(bytes);
return result;
@@ -117,31 +115,29 @@ static PyObject *py_leb128_pack_leb128(PyObject *self, PyObject *args)
{
PyObject *result; /* Valeur à retourner */
leb128_t value; /* Valeur à manipuler */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
int ret; /* Bilan de lecture des args. */
- bool status; /* Bilan de l'opération */
-
-#define LEB128_PACK_LEB128_METHOD PYTHON_METHOD_DEF \
-( \
- pack_leb128, "value, pbuf", \
- METH_VARARGS, py_leb128, \
- "Pack a signed LEB128 value into a data buffer.\n" \
- "\n" \
- "The *value* is an integer value. The *pbuf* argument has to" \
- " be a pychrysalide.common.PackedBuffer instance where data" \
- " will be appended.\n" \
- "\n" \
- "The returned value is the operation status: *True* for" \
- " success, *False* for failure." \
+ size_t count; /* Nombre d'octets produits */
+ void *bytes; /* Octets de représentation */
+
+#define LEB128_PACK_LEB128_METHOD PYTHON_METHOD_DEF \
+( \
+ pack_leb128, "value", \
+ METH_VARARGS, py_leb128, \
+ "Pack a signed LEB128 value into bytes.\n" \
+ "\n" \
+ "The *value* has to be an integer value.\n" \
+ "\n" \
+ "The returned value is byte data." \
)
- ret = PyArg_ParseTuple(args, "O&O&", convert_to_leb128_value, &value, convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "O&", convert_to_leb128_value, &value);
if (!ret) return NULL;
- status = pack_leb128(&value, pbuf);
+ bytes = pack_leb128(&value, &count);
+
+ result = PyBytes_FromStringAndSize(bytes, count);
- result = status ? Py_True : Py_False;
- Py_INCREF(result);
+ free(bytes);
return result;
@@ -164,33 +160,42 @@ static PyObject *py_leb128_pack_leb128(PyObject *self, PyObject *args)
static PyObject *py_leb128_unpack_uleb128(PyObject *self, PyObject *args)
{
PyObject *result; /* Valeur à retourner */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
+ const char *bytes; /* Octets brutes transmis */
+ Py_ssize_t count; /* Quantité de ces octets */
int ret; /* Bilan de lecture des args. */
+ const void *pos; /* Tëte de lecture */
+ const void *max; /* Position de lecture maximale*/
uleb128_t value; /* Valeur à manipuler */
bool status; /* Bilan de l'opération */
#define LEB128_UNPACK_ULEB128_METHOD PYTHON_METHOD_DEF \
( \
- unpack_uleb128, "pbuf", \
+ unpack_uleb128, "buf", \
METH_VARARGS, py_leb128, \
- "Unpack an unsigned LEB128 value into a data buffer.\n" \
+ "Unpack an unsigned LEB128 value from bytes.\n" \
"\n" \
- "The *pbuf* argument has to be a" \
- " pychrysalide.common.PackedBuffer instance from where data" \
- " will be read.\n" \
+ "The *buf* argument needs to be bytes with enough data aimed" \
+ " to get translated into an unsigned LEB128 value.\n" \
"\n" \
"The returned value depends on the operation status: *None*" \
- " for failure or a integer value for success." \
+ " for failure or a tuple with two items for success: the" \
+ " decoded value and the remaining bytes." \
)
- ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "y#", &bytes, &count);
if (!ret) return NULL;
- status = unpack_uleb128(&value, pbuf);
+ pos = bytes;
+ max = bytes + count;
- if (status)
- result = PyLong_FromUnsignedLongLong(value);
+ status = unpack_uleb128(&value, &pos, max);
+ if (status)
+ {
+ result = PyTuple_New(2);
+ PyTuple_SetItem(result, 0, PyLong_FromUnsignedLongLong(value));
+ PyTuple_SetItem(result, 1, PyBytes_FromStringAndSize(pos, (char *)max - (char *)pos));
+ }
else
{
result = Py_None;
@@ -218,33 +223,43 @@ static PyObject *py_leb128_unpack_uleb128(PyObject *self, PyObject *args)
static PyObject *py_leb128_unpack_leb128(PyObject *self, PyObject *args)
{
PyObject *result; /* Valeur à retourner */
- packed_buffer_t *pbuf; /* Tampon de données à employer*/
+ const char *bytes; /* Octets brutes transmis */
+ Py_ssize_t count; /* Quantité de ces octets */
int ret; /* Bilan de lecture des args. */
+ const void *pos; /* Tëte de lecture */
+ const void *max; /* Position de lecture maximale*/
leb128_t value; /* Valeur à manipuler */
bool status; /* Bilan de l'opération */
#define LEB128_UNPACK_LEB128_METHOD PYTHON_METHOD_DEF \
( \
- unpack_leb128, "pbuf", \
+ unpack_leb128, "buf", \
METH_VARARGS, py_leb128, \
- "Unpack a signed LEB128 value into a data buffer.\n" \
+ "Unpack a signed LEB128 value from bytes.\n" \
"\n" \
- "The *pbuf* argument has to be a" \
- " pychrysalide.common.PackedBuffer instance from where data" \
- " will be read.\n" \
+ "\n" \
+ "The *buf* argument needs to be bytes with enough data aimed" \
+ " to get translated into a signed LEB128 value.\n" \
"\n" \
"The returned value depends on the operation status: *None*" \
- " for failure or a integer value for success." \
+ " for failure or a tuple with two items for success: the" \
+ " decoded value and the remaining bytes." \
)
- ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+ ret = PyArg_ParseTuple(args, "y#", &bytes, &count);
if (!ret) return NULL;
- status = unpack_leb128(&value, pbuf);
+ pos = bytes;
+ max = bytes + count;
- if (status)
- result = PyLong_FromLongLong(value);
+ status = unpack_leb128(&value, &pos, max);
+ if (status)
+ {
+ result = PyTuple_New(2);
+ PyTuple_SetItem(result, 0, PyLong_FromLongLong(value));
+ PyTuple_SetItem(result, 1, PyBytes_FromStringAndSize(pos, (char *)max - (char *)pos));
+ }
else
{
result = Py_None;