Skip to content

Commit

Permalink
data: fix DNode.new schema handling
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Samuel Gauthier <[email protected]>
  • Loading branch information
nvxf authored and samuel-gauthier committed Jan 30, 2024
1 parent 5681ef0 commit ae3b320
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
22 changes: 16 additions & 6 deletions libyang/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,7 @@ def eval_xpath(self, xpath: str):
return False

def path(self) -> str:
path = lib.lyd_path(self.cdata, lib.LYD_PATH_STD, ffi.NULL, 0)
try:
return c2str(path)
finally:
lib.free(path)
return self._get_path(self.cdata)

def validate(
self,
Expand Down Expand Up @@ -923,11 +919,25 @@ def _decorator(nodeclass):
@classmethod
def new(cls, context: "libyang.Context", cdata) -> "DNode":
cdata = ffi.cast("struct lyd_node *", cdata)
nodecls = cls.NODETYPE_CLASS.get(cdata.schema.nodetype, None)
if not cdata.schema:
schemas = list(context.find_path(cls._get_path(cdata)))
if len(schemas) != 1:
raise LibyangError("Unable to determine schema")
nodecls = cls.NODETYPE_CLASS.get(schemas[0].nodetype(), None)
else:
nodecls = cls.NODETYPE_CLASS.get(cdata.schema.nodetype, None)
if nodecls is None:
raise TypeError("node type %s not implemented" % cdata.schema.nodetype)
return nodecls(context, cdata)

@staticmethod
def _get_path(cdata) -> str:
path = lib.lyd_path(cdata, lib.LYD_PATH_STD, ffi.NULL, 0)
try:
return c2str(path)
finally:
lib.free(path)


# -------------------------------------------------------------------------------------
@DNode.register(SNode.CONTAINER)
Expand Down
11 changes: 11 additions & 0 deletions tests/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -949,3 +949,14 @@ def test_dnode_insert_sibling(self):
sibling = next(dnode1.siblings(include_self=False), None)
self.assertIsInstance(sibling, DLeaf)
self.assertEqual(sibling.cdata, dnode2.cdata)

def test_dnode_new_opaq_find_one(self):
root = self.ctx.create_data_path(path="/yolo-system:conf")
root.new_path(
"hostname",
None,
opt_opaq=True,
)
dnode = root.find_one("/yolo-system:conf/hostname")

self.assertIsInstance(dnode, DLeaf)

0 comments on commit ae3b320

Please sign in to comment.