Skip to content

Commit ae3b320

Browse files
nvxfsamuel-gauthier
authored andcommitted
data: fix DNode.new schema handling
In case of a call to DNode.new with cdata containing an opaque node the new method tries to access cdata.schema.nodetype, which results in a NULL pointer dereference. To get the schema for an opaque node retrieve the schema from the context using the path of the node. Fixes: #73 Signed-off-by: nvxf <68589039+nvxf@users.noreply.github.com> Acked-by: Samuel Gauthier <samuel.gauthier@6wind.com>
1 parent 5681ef0 commit ae3b320

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

libyang/data.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,11 +417,7 @@ def eval_xpath(self, xpath: str):
417417
return False
418418

419419
def path(self) -> str:
420-
path = lib.lyd_path(self.cdata, lib.LYD_PATH_STD, ffi.NULL, 0)
421-
try:
422-
return c2str(path)
423-
finally:
424-
lib.free(path)
420+
return self._get_path(self.cdata)
425421

426422
def validate(
427423
self,
@@ -923,11 +919,25 @@ def _decorator(nodeclass):
923919
@classmethod
924920
def new(cls, context: "libyang.Context", cdata) -> "DNode":
925921
cdata = ffi.cast("struct lyd_node *", cdata)
926-
nodecls = cls.NODETYPE_CLASS.get(cdata.schema.nodetype, None)
922+
if not cdata.schema:
923+
schemas = list(context.find_path(cls._get_path(cdata)))
924+
if len(schemas) != 1:
925+
raise LibyangError("Unable to determine schema")
926+
nodecls = cls.NODETYPE_CLASS.get(schemas[0].nodetype(), None)
927+
else:
928+
nodecls = cls.NODETYPE_CLASS.get(cdata.schema.nodetype, None)
927929
if nodecls is None:
928930
raise TypeError("node type %s not implemented" % cdata.schema.nodetype)
929931
return nodecls(context, cdata)
930932

933+
@staticmethod
934+
def _get_path(cdata) -> str:
935+
path = lib.lyd_path(cdata, lib.LYD_PATH_STD, ffi.NULL, 0)
936+
try:
937+
return c2str(path)
938+
finally:
939+
lib.free(path)
940+
931941

932942
# -------------------------------------------------------------------------------------
933943
@DNode.register(SNode.CONTAINER)

tests/test_data.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,3 +949,14 @@ def test_dnode_insert_sibling(self):
949949
sibling = next(dnode1.siblings(include_self=False), None)
950950
self.assertIsInstance(sibling, DLeaf)
951951
self.assertEqual(sibling.cdata, dnode2.cdata)
952+
953+
def test_dnode_new_opaq_find_one(self):
954+
root = self.ctx.create_data_path(path="/yolo-system:conf")
955+
root.new_path(
956+
"hostname",
957+
None,
958+
opt_opaq=True,
959+
)
960+
dnode = root.find_one("/yolo-system:conf/hostname")
961+
962+
self.assertIsInstance(dnode, DLeaf)

0 commit comments

Comments
 (0)