1 /*
2 * Python object wrapper of libesedb_column_t
3 *
4 * Copyright (C) 2009-2021, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <types.h>
24
25 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
26 #include <stdlib.h>
27 #endif
28
29 #include "pyesedb_column.h"
30 #include "pyesedb_error.h"
31 #include "pyesedb_libcerror.h"
32 #include "pyesedb_libesedb.h"
33 #include "pyesedb_python.h"
34 #include "pyesedb_unused.h"
35
36 PyMethodDef pyesedb_column_object_methods[] = {
37
38 { "get_identifier",
39 (PyCFunction) pyesedb_column_get_identifier,
40 METH_NOARGS,
41 "get_identifier() -> Integer\n"
42 "\n"
43 "Retrieves the identifier." },
44
45 { "get_type",
46 (PyCFunction) pyesedb_column_get_type,
47 METH_NOARGS,
48 "get_type() -> Integer\n"
49 "\n"
50 "Retrieves the type." },
51
52 { "get_name",
53 (PyCFunction) pyesedb_column_get_name,
54 METH_NOARGS,
55 "get_name() -> Unicode string\n"
56 "\n"
57 "Retrieves the name." },
58
59 /* Sentinel */
60 { NULL, NULL, 0, NULL }
61 };
62
63 PyGetSetDef pyesedb_column_object_get_set_definitions[] = {
64
65 { "identifier",
66 (getter) pyesedb_column_get_identifier,
67 (setter) 0,
68 "The identifier.",
69 NULL },
70
71 { "type",
72 (getter) pyesedb_column_get_type,
73 (setter) 0,
74 "The type.",
75 NULL },
76
77 { "name",
78 (getter) pyesedb_column_get_name,
79 (setter) 0,
80 "The name.",
81 NULL },
82
83 /* Sentinel */
84 { NULL, NULL, NULL, NULL, NULL }
85 };
86
87 PyTypeObject pyesedb_column_type_object = {
88 PyVarObject_HEAD_INIT( NULL, 0 )
89
90 /* tp_name */
91 "pyesedb.column",
92 /* tp_basicsize */
93 sizeof( pyesedb_column_t ),
94 /* tp_itemsize */
95 0,
96 /* tp_dealloc */
97 (destructor) pyesedb_column_free,
98 /* tp_print */
99 0,
100 /* tp_getattr */
101 0,
102 /* tp_setattr */
103 0,
104 /* tp_compare */
105 0,
106 /* tp_repr */
107 0,
108 /* tp_as_number */
109 0,
110 /* tp_as_sequence */
111 0,
112 /* tp_as_mapping */
113 0,
114 /* tp_hash */
115 0,
116 /* tp_call */
117 0,
118 /* tp_str */
119 0,
120 /* tp_getattro */
121 0,
122 /* tp_setattro */
123 0,
124 /* tp_as_buffer */
125 0,
126 /* tp_flags */
127 Py_TPFLAGS_DEFAULT,
128 /* tp_doc */
129 "pyesedb column object (wraps libesedb_column_t)",
130 /* tp_traverse */
131 0,
132 /* tp_clear */
133 0,
134 /* tp_richcompare */
135 0,
136 /* tp_weaklistoffset */
137 0,
138 /* tp_iter */
139 0,
140 /* tp_iternext */
141 0,
142 /* tp_methods */
143 pyesedb_column_object_methods,
144 /* tp_members */
145 0,
146 /* tp_getset */
147 pyesedb_column_object_get_set_definitions,
148 /* tp_base */
149 0,
150 /* tp_dict */
151 0,
152 /* tp_descr_get */
153 0,
154 /* tp_descr_set */
155 0,
156 /* tp_dictoffset */
157 0,
158 /* tp_init */
159 (initproc) pyesedb_column_init,
160 /* tp_alloc */
161 0,
162 /* tp_new */
163 0,
164 /* tp_free */
165 0,
166 /* tp_is_gc */
167 0,
168 /* tp_bases */
169 NULL,
170 /* tp_mro */
171 NULL,
172 /* tp_cache */
173 NULL,
174 /* tp_subclasses */
175 NULL,
176 /* tp_weaklist */
177 NULL,
178 /* tp_del */
179 0
180 };
181
182 /* Creates a new column object
183 * Returns a Python object if successful or NULL on error
184 */
pyesedb_column_new(libesedb_column_t * column,PyObject * parent_object)185 PyObject *pyesedb_column_new(
186 libesedb_column_t *column,
187 PyObject *parent_object )
188 {
189 pyesedb_column_t *pyesedb_column = NULL;
190 static char *function = "pyesedb_column_new";
191
192 if( column == NULL )
193 {
194 PyErr_Format(
195 PyExc_ValueError,
196 "%s: invalid column.",
197 function );
198
199 return( NULL );
200 }
201 /* PyObject_New does not invoke tp_init
202 */
203 pyesedb_column = PyObject_New(
204 struct pyesedb_column,
205 &pyesedb_column_type_object );
206
207 if( pyesedb_column == NULL )
208 {
209 PyErr_Format(
210 PyExc_MemoryError,
211 "%s: unable to initialize column.",
212 function );
213
214 goto on_error;
215 }
216 pyesedb_column->column = column;
217 pyesedb_column->parent_object = parent_object;
218
219 if( pyesedb_column->parent_object != NULL )
220 {
221 Py_IncRef(
222 pyesedb_column->parent_object );
223 }
224 return( (PyObject *) pyesedb_column );
225
226 on_error:
227 if( pyesedb_column != NULL )
228 {
229 Py_DecRef(
230 (PyObject *) pyesedb_column );
231 }
232 return( NULL );
233 }
234
235 /* Initializes a column object
236 * Returns 0 if successful or -1 on error
237 */
pyesedb_column_init(pyesedb_column_t * pyesedb_column)238 int pyesedb_column_init(
239 pyesedb_column_t *pyesedb_column )
240 {
241 static char *function = "pyesedb_column_init";
242
243 if( pyesedb_column == NULL )
244 {
245 PyErr_Format(
246 PyExc_ValueError,
247 "%s: invalid column.",
248 function );
249
250 return( -1 );
251 }
252 /* Make sure libesedb column is set to NULL
253 */
254 pyesedb_column->column = NULL;
255
256 PyErr_Format(
257 PyExc_NotImplementedError,
258 "%s: initialize of column not supported.",
259 function );
260
261 return( -1 );
262 }
263
264 /* Frees a column object
265 */
pyesedb_column_free(pyesedb_column_t * pyesedb_column)266 void pyesedb_column_free(
267 pyesedb_column_t *pyesedb_column )
268 {
269 struct _typeobject *ob_type = NULL;
270 libcerror_error_t *error = NULL;
271 static char *function = "pyesedb_column_free";
272 int result = 0;
273
274 if( pyesedb_column == NULL )
275 {
276 PyErr_Format(
277 PyExc_ValueError,
278 "%s: invalid column.",
279 function );
280
281 return;
282 }
283 ob_type = Py_TYPE(
284 pyesedb_column );
285
286 if( ob_type == NULL )
287 {
288 PyErr_Format(
289 PyExc_ValueError,
290 "%s: missing ob_type.",
291 function );
292
293 return;
294 }
295 if( ob_type->tp_free == NULL )
296 {
297 PyErr_Format(
298 PyExc_ValueError,
299 "%s: invalid ob_type - missing tp_free.",
300 function );
301
302 return;
303 }
304 if( pyesedb_column->column != NULL )
305 {
306 Py_BEGIN_ALLOW_THREADS
307
308 result = libesedb_column_free(
309 &( pyesedb_column->column ),
310 &error );
311
312 Py_END_ALLOW_THREADS
313
314 if( result != 1 )
315 {
316 pyesedb_error_raise(
317 error,
318 PyExc_MemoryError,
319 "%s: unable to free libesedb column.",
320 function );
321
322 libcerror_error_free(
323 &error );
324 }
325 }
326 if( pyesedb_column->parent_object != NULL )
327 {
328 Py_DecRef(
329 pyesedb_column->parent_object );
330 }
331 ob_type->tp_free(
332 (PyObject*) pyesedb_column );
333 }
334
335 /* Retrieves the identifier
336 * Returns a Python object if successful or NULL on error
337 */
pyesedb_column_get_identifier(pyesedb_column_t * pyesedb_column,PyObject * arguments PYESEDB_ATTRIBUTE_UNUSED)338 PyObject *pyesedb_column_get_identifier(
339 pyesedb_column_t *pyesedb_column,
340 PyObject *arguments PYESEDB_ATTRIBUTE_UNUSED )
341 {
342 PyObject *integer_object = NULL;
343 libcerror_error_t *error = NULL;
344 static char *function = "pyesedb_column_get_identifier";
345 uint32_t value_32bit = 0;
346 int result = 0;
347
348 PYESEDB_UNREFERENCED_PARAMETER( arguments )
349
350 if( pyesedb_column == NULL )
351 {
352 PyErr_Format(
353 PyExc_ValueError,
354 "%s: invalid column.",
355 function );
356
357 return( NULL );
358 }
359 Py_BEGIN_ALLOW_THREADS
360
361 result = libesedb_column_get_identifier(
362 pyesedb_column->column,
363 &value_32bit,
364 &error );
365
366 Py_END_ALLOW_THREADS
367
368 if( result != 1 )
369 {
370 pyesedb_error_raise(
371 error,
372 PyExc_IOError,
373 "%s: unable to retrieve identifier.",
374 function );
375
376 libcerror_error_free(
377 &error );
378
379 return( NULL );
380 }
381 integer_object = PyLong_FromUnsignedLong(
382 (unsigned long) value_32bit );
383
384 return( integer_object );
385 }
386
387 /* Retrieves the type
388 * Returns a Python object if successful or NULL on error
389 */
pyesedb_column_get_type(pyesedb_column_t * pyesedb_column,PyObject * arguments PYESEDB_ATTRIBUTE_UNUSED)390 PyObject *pyesedb_column_get_type(
391 pyesedb_column_t *pyesedb_column,
392 PyObject *arguments PYESEDB_ATTRIBUTE_UNUSED )
393 {
394 PyObject *integer_object = NULL;
395 libcerror_error_t *error = NULL;
396 static char *function = "pyesedb_column_get_type";
397 uint32_t value_32bit = 0;
398 int result = 0;
399
400 PYESEDB_UNREFERENCED_PARAMETER( arguments )
401
402 if( pyesedb_column == NULL )
403 {
404 PyErr_Format(
405 PyExc_ValueError,
406 "%s: invalid column.",
407 function );
408
409 return( NULL );
410 }
411 Py_BEGIN_ALLOW_THREADS
412
413 result = libesedb_column_get_type(
414 pyesedb_column->column,
415 &value_32bit,
416 &error );
417
418 Py_END_ALLOW_THREADS
419
420 if( result != 1 )
421 {
422 pyesedb_error_raise(
423 error,
424 PyExc_IOError,
425 "%s: unable to retrieve type.",
426 function );
427
428 libcerror_error_free(
429 &error );
430
431 return( NULL );
432 }
433 integer_object = PyLong_FromUnsignedLong(
434 (unsigned long) value_32bit );
435
436 return( integer_object );
437 }
438
439 /* Retrieves the name
440 * Returns a Python object if successful or NULL on error
441 */
pyesedb_column_get_name(pyesedb_column_t * pyesedb_column,PyObject * arguments PYESEDB_ATTRIBUTE_UNUSED)442 PyObject *pyesedb_column_get_name(
443 pyesedb_column_t *pyesedb_column,
444 PyObject *arguments PYESEDB_ATTRIBUTE_UNUSED )
445 {
446 PyObject *string_object = NULL;
447 libcerror_error_t *error = NULL;
448 const char *errors = NULL;
449 static char *function = "pyesedb_column_get_name";
450 char *utf8_string = NULL;
451 size_t utf8_string_size = 0;
452 int result = 0;
453
454 PYESEDB_UNREFERENCED_PARAMETER( arguments )
455
456 if( pyesedb_column == NULL )
457 {
458 PyErr_Format(
459 PyExc_ValueError,
460 "%s: invalid column.",
461 function );
462
463 return( NULL );
464 }
465 Py_BEGIN_ALLOW_THREADS
466
467 result = libesedb_column_get_utf8_name_size(
468 pyesedb_column->column,
469 &utf8_string_size,
470 &error );
471
472 Py_END_ALLOW_THREADS
473
474 if( result == -1 )
475 {
476 pyesedb_error_raise(
477 error,
478 PyExc_IOError,
479 "%s: unable to determine size of name as UTF-8 string.",
480 function );
481
482 libcerror_error_free(
483 &error );
484
485 goto on_error;
486 }
487 else if( ( result == 0 )
488 || ( utf8_string_size == 0 ) )
489 {
490 Py_IncRef(
491 Py_None );
492
493 return( Py_None );
494 }
495 utf8_string = (char *) PyMem_Malloc(
496 sizeof( char ) * utf8_string_size );
497
498 if( utf8_string == NULL )
499 {
500 PyErr_Format(
501 PyExc_MemoryError,
502 "%s: unable to create UTF-8 string.",
503 function );
504
505 goto on_error;
506 }
507 Py_BEGIN_ALLOW_THREADS
508
509 result = libesedb_column_get_utf8_name(
510 pyesedb_column->column,
511 (uint8_t *) utf8_string,
512 utf8_string_size,
513 &error );
514
515 Py_END_ALLOW_THREADS
516
517 if( result != 1 )
518 {
519 pyesedb_error_raise(
520 error,
521 PyExc_IOError,
522 "%s: unable to retrieve name as UTF-8 string.",
523 function );
524
525 libcerror_error_free(
526 &error );
527
528 goto on_error;
529 }
530 /* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes
531 * the end of string character is part of the string.
532 */
533 string_object = PyUnicode_DecodeUTF8(
534 utf8_string,
535 (Py_ssize_t) utf8_string_size - 1,
536 errors );
537
538 if( string_object == NULL )
539 {
540 PyErr_Format(
541 PyExc_IOError,
542 "%s: unable to convert UTF-8 string into Unicode object.",
543 function );
544
545 goto on_error;
546 }
547 PyMem_Free(
548 utf8_string );
549
550 return( string_object );
551
552 on_error:
553 if( utf8_string != NULL )
554 {
555 PyMem_Free(
556 utf8_string );
557 }
558 return( NULL );
559 }
560
561