LCOV - code coverage report
Current view: top level - lib/talloc - pytalloc_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 105 144 72.9 %
Date: 2024-04-21 15:09:00 Functions: 17 19 89.5 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Python/Talloc glue
       4             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
       5             :    
       6             :      ** NOTE! The following LGPL license applies to the talloc
       7             :      ** library. This does NOT imply that all of Samba is released
       8             :      ** under the LGPL
       9             : 
      10             :    This library is free software; you can redistribute it and/or
      11             :    modify it under the terms of the GNU Lesser General Public
      12             :    License as published by the Free Software Foundation; either
      13             :    version 3 of the License, or (at your option) any later version.
      14             : 
      15             :    This library is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :    Lesser General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU Lesser General Public
      21             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "lib/replace/system/python.h"
      25             : #include "replace.h"
      26             : #include <talloc.h>
      27             : #include "pytalloc.h"
      28             : #include <assert.h>
      29             : #include "pytalloc_private.h"
      30             : 
      31             : static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type,
      32             :                                          TALLOC_CTX *mem_ctx, void *ptr, bool steal);
      33             : 
      34    83838170 : _PUBLIC_ PyTypeObject *pytalloc_GetObjectType(void)
      35             : {
      36    69629331 :         static PyTypeObject *type = NULL;
      37    69629331 :         PyObject *mod;
      38             : 
      39    83838170 :         mod = PyImport_ImportModule("talloc");
      40    83838170 :         if (mod == NULL) {
      41           0 :                 return NULL;
      42             :         }
      43             : 
      44    83838170 :         type = (PyTypeObject *)PyObject_GetAttrString(mod, "Object");
      45    69629331 :         Py_DECREF(mod);
      46             : 
      47    83838170 :         return type;
      48             : }
      49             : 
      50   255189362 : _PUBLIC_ PyTypeObject *pytalloc_GetBaseObjectType(void)
      51             : {
      52   213306913 :         static PyTypeObject *type = NULL;
      53   213306913 :         PyObject *mod;
      54             : 
      55   255189362 :         mod = PyImport_ImportModule("talloc");
      56   255189362 :         if (mod == NULL) {
      57           0 :                 return NULL;
      58             :         }
      59             : 
      60   255189362 :         type = (PyTypeObject *)PyObject_GetAttrString(mod, "BaseObject");
      61   213306913 :         Py_DECREF(mod);
      62             : 
      63   255189362 :         return type;
      64             : }
      65             : 
      66     5152212 : static PyTypeObject *pytalloc_GetGenericObjectType(void)
      67             : {
      68     4239041 :         static PyTypeObject *type = NULL;
      69     4239041 :         PyObject *mod;
      70             : 
      71     5152212 :         mod = PyImport_ImportModule("talloc");
      72     5152212 :         if (mod == NULL) {
      73           0 :                 return NULL;
      74             :         }
      75             : 
      76     5152212 :         type = (PyTypeObject *)PyObject_GetAttrString(mod, "GenericObject");
      77     4239041 :         Py_DECREF(mod);
      78             : 
      79     5152212 :         return type;
      80             : }
      81             : 
      82             : /**
      83             :  * Import an existing talloc pointer into a Python object.
      84             :  */
      85         130 : _PUBLIC_ PyObject *pytalloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
      86             :                                      void *ptr)
      87             : {
      88         130 :         return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, true);
      89             : }
      90             : 
      91             : /**
      92             :  * Import an existing talloc pointer into a Python object.
      93             :  */
      94    18107684 : _PUBLIC_ PyObject *pytalloc_steal(PyTypeObject *py_type, void *ptr)
      95             : {
      96    18107684 :         return pytalloc_steal_or_reference(py_type, ptr, ptr, true);
      97             : }
      98             : 
      99             : 
     100             : /**
     101             :  * Import an existing talloc pointer into a Python object, leaving the
     102             :  * original parent, and creating a reference to the object in the python
     103             :  * object.
     104             :  *
     105             :  * We remember the object we hold the reference to (a
     106             :  * possibly-non-talloc pointer), the existing parent (typically the
     107             :  * start of the array) and the new referenced parent.  That way we can
     108             :  * cope with the fact that we will have multiple parents, one per time
     109             :  * python sees the object.
     110             :  */
     111    65717446 : _PUBLIC_ PyObject *pytalloc_reference_ex(PyTypeObject *py_type,
     112             :                                          TALLOC_CTX *mem_ctx, void *ptr)
     113             : {
     114    65717446 :         return pytalloc_steal_or_reference(py_type, mem_ctx, ptr, false);
     115             : }
     116             : 
     117             : 
     118             : /**
     119             :  * Internal function that either steals or references the talloc
     120             :  * pointer into a new talloc context.
     121             :  */
     122    83825260 : static PyObject *pytalloc_steal_or_reference(PyTypeObject *py_type,
     123             :                                          TALLOC_CTX *mem_ctx, void *ptr, bool steal)
     124             : {
     125    83825260 :         bool ok = false;
     126    83825260 :         TALLOC_CTX *talloc_ctx = NULL;
     127    83825260 :         bool is_baseobject = false;
     128    83825260 :         PyObject *obj = NULL;
     129    83825260 :         PyTypeObject *BaseObjectType = NULL, *ObjectType = NULL;
     130             : 
     131    83825260 :         BaseObjectType = pytalloc_GetBaseObjectType();
     132    83825260 :         if (BaseObjectType == NULL) {
     133           0 :                 goto err;
     134             :         }
     135    83825260 :         ObjectType = pytalloc_GetObjectType();
     136    83825260 :         if (ObjectType == NULL) {
     137           0 :                 goto err;
     138             :         }
     139             : 
     140             :         /* this should have been tested by caller */
     141    83825260 :         if (mem_ctx == NULL) {
     142           0 :                 return PyErr_NoMemory();
     143             :         }
     144             : 
     145    83825260 :         is_baseobject = PyType_IsSubtype(py_type, BaseObjectType);
     146    83825260 :         if (!is_baseobject) {
     147           9 :                 if (!PyType_IsSubtype(py_type, ObjectType)) {
     148           0 :                         PyErr_SetString(PyExc_TypeError,
     149             :                                 "Expected type based on talloc");
     150           0 :                         return NULL;
     151             :                 }
     152             :         }
     153             : 
     154    83825260 :         obj = py_type->tp_alloc(py_type, 0);
     155    83825260 :         if (obj == NULL) {
     156           0 :                 goto err;
     157             :         }
     158             : 
     159    83825260 :         talloc_ctx = talloc_new(NULL);
     160    83825260 :         if (talloc_ctx == NULL) {
     161           0 :                 PyErr_NoMemory();
     162           0 :                 goto err;
     163             :         }
     164             : 
     165    83825260 :         if (steal) {
     166    18107814 :                 ok = (talloc_steal(talloc_ctx, mem_ctx) != NULL);
     167             :         } else {
     168    65717446 :                 ok = (talloc_reference(talloc_ctx, mem_ctx) != NULL);
     169             :         }
     170    83825260 :         if (!ok) {
     171           0 :                 goto err;
     172             :         }
     173    83825260 :         talloc_set_name_const(talloc_ctx, py_type->tp_name);
     174             : 
     175    83825260 :         if (is_baseobject) {
     176    83825251 :                 pytalloc_BaseObject *ret = (pytalloc_BaseObject*)obj;
     177    83825251 :                 ret->talloc_ctx = talloc_ctx;
     178    83825251 :                 ret->talloc_ptr_ctx = mem_ctx;
     179    83825251 :                 ret->ptr = ptr;
     180             :         } else {
     181           9 :                 pytalloc_Object *ret = (pytalloc_Object*)obj;
     182           9 :                 ret->talloc_ctx = talloc_ctx;
     183           9 :                 ret->ptr = ptr;
     184             :         }
     185    14206707 :         return obj;
     186             : 
     187           0 : err:
     188           0 :         TALLOC_FREE(talloc_ctx);
     189           0 :         Py_XDECREF(obj);
     190           0 :         return NULL;
     191             : }
     192             : 
     193             : /*
     194             :  * Wrap a generic talloc pointer into a talloc.GenericObject,
     195             :  * this is a subclass of talloc.BaseObject.
     196             :  */
     197         130 : _PUBLIC_ PyObject *pytalloc_GenericObject_steal_ex(TALLOC_CTX *mem_ctx, void *ptr)
     198             : {
     199         130 :         PyTypeObject *tp = pytalloc_GetGenericObjectType();
     200         130 :         return pytalloc_steal_ex(tp, mem_ctx, ptr);
     201             : }
     202             : 
     203             : /*
     204             :  * Wrap a generic talloc pointer into a talloc.GenericObject,
     205             :  * this is a subclass of talloc.BaseObject.
     206             :  */
     207     5152082 : _PUBLIC_ PyObject *pytalloc_GenericObject_reference_ex(TALLOC_CTX *mem_ctx, void *ptr)
     208             : {
     209     5152082 :         PyTypeObject *tp = pytalloc_GetGenericObjectType();
     210     5152082 :         return pytalloc_reference_ex(tp, mem_ctx, ptr);
     211             : }
     212             : 
     213          53 : _PUBLIC_ int pytalloc_Check(PyObject *obj)
     214             : {
     215          53 :         PyTypeObject *tp = pytalloc_GetObjectType();
     216             : 
     217          53 :         return PyObject_TypeCheck(obj, tp);
     218             : }
     219             : 
     220   171300866 : _PUBLIC_ int pytalloc_BaseObject_check(PyObject *obj)
     221             : {
     222   171300866 :         PyTypeObject *tp = pytalloc_GetBaseObjectType();
     223             : 
     224   171300866 :         return PyObject_TypeCheck(obj, tp);
     225             : }
     226             : 
     227     5509658 : _PUBLIC_ size_t pytalloc_BaseObject_size(void)
     228             : {
     229     5509658 :         return sizeof(pytalloc_BaseObject);
     230             : }
     231             : 
     232      694102 : static void *_pytalloc_get_checked_type(PyObject *py_obj, const char *type_name,
     233             :                                         bool check_only, const char *function)
     234             : {
     235      487186 :         TALLOC_CTX *mem_ctx;
     236      694102 :         void *ptr = NULL;
     237      487186 :         void *type_obj;
     238             : 
     239      694102 :         mem_ctx = _pytalloc_get_mem_ctx(py_obj);
     240      694102 :         ptr = _pytalloc_get_ptr(py_obj);
     241             : 
     242      694102 :         if (mem_ctx != ptr || ptr == NULL) {
     243           0 :                 if (check_only) {
     244           0 :                         return NULL;
     245             :                 }
     246             : 
     247           0 :                 PyErr_Format(PyExc_TypeError, "%s: expected %s, "
     248             :                              "but the pointer is no talloc pointer, "
     249             :                              "pytalloc_get_ptr() would get the raw pointer.",
     250             :                              function, type_name);
     251           0 :                 return NULL;
     252             :         }
     253             : 
     254      694102 :         type_obj = talloc_check_name(ptr, type_name);
     255      694102 :         if (type_obj == NULL) {
     256           0 :                 const char *name = NULL;
     257             : 
     258           0 :                 if (check_only) {
     259           0 :                         return NULL;
     260             :                 }
     261             : 
     262           0 :                 name = talloc_get_name(ptr);
     263           0 :                 PyErr_Format(PyExc_TypeError, "%s: expected %s, got %s",
     264             :                              function, type_name, name);
     265           0 :                 return NULL;
     266             :         }
     267             : 
     268      206916 :         return ptr;
     269             : }
     270             : 
     271           0 : _PUBLIC_ int _pytalloc_check_type(PyObject *py_obj, const char *type_name)
     272             : {
     273           0 :         void *ptr = NULL;
     274             : 
     275           0 :         ptr = _pytalloc_get_checked_type(py_obj, type_name,
     276             :                                          true, /* check_only */
     277             :                                          "pytalloc_check_type");
     278           0 :         if (ptr == NULL) {
     279           0 :                 return 0;
     280             :         }
     281             : 
     282           0 :         return 1;
     283             : }
     284             : 
     285      694102 : _PUBLIC_ void *_pytalloc_get_type(PyObject *py_obj, const char *type_name)
     286             : {
     287      694102 :         return _pytalloc_get_checked_type(py_obj, type_name,
     288             :                                           false, /* not check_only */
     289             :                                           "pytalloc_get_type");
     290             : }
     291             : 
     292   146347643 : _PUBLIC_ void *_pytalloc_get_ptr(PyObject *py_obj)
     293             : {
     294   146347643 :         if (pytalloc_BaseObject_check(py_obj)) {
     295   146347594 :                 return ((pytalloc_BaseObject *)py_obj)->ptr;
     296             :         }
     297          49 :         if (pytalloc_Check(py_obj)) {
     298          27 :                 return ((pytalloc_Object *)py_obj)->ptr;
     299             :         }
     300           0 :         return NULL;
     301             : }
     302             : 
     303    24953223 : _PUBLIC_ TALLOC_CTX *_pytalloc_get_mem_ctx(PyObject *py_obj)
     304             : {
     305    24953223 :         if (pytalloc_BaseObject_check(py_obj)) {
     306    24953219 :                 return ((pytalloc_BaseObject *)py_obj)->talloc_ptr_ctx;
     307             :         }
     308           4 :         if (pytalloc_Check(py_obj)) {
     309           2 :                 return ((pytalloc_Object *)py_obj)->talloc_ctx;
     310             :         }
     311           1 :         return NULL;
     312             : }
     313             : 
     314       63227 : _PUBLIC_ int pytalloc_BaseObject_PyType_Ready(PyTypeObject *type)
     315             : {
     316       63227 :         PyTypeObject *talloc_type = pytalloc_GetBaseObjectType();
     317       63227 :         if (talloc_type == NULL) {
     318           0 :                 return -1;
     319             :         }
     320             : 
     321       63227 :         type->tp_base = talloc_type;
     322       63227 :         type->tp_basicsize = pytalloc_BaseObject_size();
     323             : 
     324       63227 :         return PyType_Ready(type);
     325             : }
     326             : 
     327           0 : _PUBLIC_ const char *_pytalloc_get_name(PyObject *obj)
     328             : {
     329           0 :         void *ptr = pytalloc_get_ptr(obj);
     330           0 :         if (ptr == NULL) {
     331           0 :                 return "non-talloc object";
     332             :         }
     333           0 :         return talloc_get_name(ptr);
     334             : }

Generated by: LCOV version 1.14