aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libctf/ChangeLog6
-rw-r--r--libctf/ctf-lookup.c4
-rw-r--r--libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.c68
-rw-r--r--libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.lk2
4 files changed, 78 insertions, 2 deletions
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index e66cf2a..5907e2f 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,11 @@
2021-09-27 Nick Alcock <nick.alcock@oracle.com>
+ * ctf-lookup.c (ctf_lookup_by_name_internal): Fix pptrtab bounds.
+ * testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.*:
+ New test.
+
+2021-09-27 Nick Alcock <nick.alcock@oracle.com>
+
* testsuite/libctf-lookup/enum-symbol.c: Remove unused label.
* testsuite/libctf-lookup/conflicting-type-syms.c: Remove unused
variables.
diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c
index fe66bc4..d1828f8 100644
--- a/libctf/ctf-lookup.c
+++ b/libctf/ctf-lookup.c
@@ -176,7 +176,7 @@ ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
int in_child = 0;
ntype = CTF_ERR;
- if (child && idx <= child->ctf_pptrtab_len)
+ if (child && idx < child->ctf_pptrtab_len)
{
ntype = child->ctf_pptrtab[idx];
if (ntype)
@@ -206,7 +206,7 @@ ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
idx = LCTF_TYPE_TO_INDEX (fp, ntype);
ntype = CTF_ERR;
- if (child && idx <= child->ctf_pptrtab_len)
+ if (child && idx < child->ctf_pptrtab_len)
{
ntype = child->ctf_pptrtab[idx];
if (ntype)
diff --git a/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.c b/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.c
new file mode 100644
index 0000000..ca42065
--- /dev/null
+++ b/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.c
@@ -0,0 +1,68 @@
+/* Make sure we can look up a pointer-to-type where the type is more than a page
+ into the parent and the child has never had a lookup before. */
+
+#include <ctf-api.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main (void)
+{
+ ctf_dict_t *pfp, *cfp;
+ ctf_encoding_t e = { CTF_INT_SIGNED, 0, sizeof (long) };
+ ctf_id_t ptype, ptrtype, type, foo;
+ size_t i;
+ int err;
+
+ if ((pfp = ctf_create (&err)) == NULL)
+ goto create_err;
+
+ if ((ptype = ctf_add_integer (pfp, CTF_ADD_NONROOT, "blah", &e)) == CTF_ERR)
+ goto create_parent;
+
+ for (i = 0; i < 4096; i++)
+ if ((foo = ctf_add_pointer (pfp, CTF_ADD_NONROOT, ptype)) == CTF_ERR)
+ goto create_parent;
+
+ if ((cfp = ctf_create (&err)) == NULL)
+ goto create_err;
+
+ if (ctf_import (cfp, pfp) < 0)
+ goto create_child;
+
+ if ((ptype = ctf_add_integer (pfp, CTF_ADD_ROOT, "foo", &e)) == CTF_ERR)
+ goto create_parent;
+
+ if ((ptrtype = ctf_add_pointer (pfp, CTF_ADD_ROOT, ptype)) == CTF_ERR)
+ goto create_parent;
+
+ if ((type = ctf_lookup_by_name (cfp, "*foo")) != CTF_ERR)
+ {
+ fprintf (stderr, "Type lookup unexpectedly succeeded: %s\n", ctf_errmsg (ctf_errno (cfp)));
+ exit (1);
+ }
+
+ if ((type = ctf_lookup_by_name (cfp, "foo *")) == CTF_ERR)
+ {
+ fprintf (stderr, "Type lookup error: %s\n", ctf_errmsg (ctf_errno (cfp)));
+ exit (1);
+ }
+
+ ctf_dict_close (cfp);
+ ctf_dict_close (pfp);
+
+ printf ("Type lookup succeeded.\n");
+
+ return 0;
+
+ create_err:
+ fprintf (stderr, "Creation failed: %s\n", ctf_errmsg (err));
+ exit (1);
+ create_parent:
+ fprintf (stderr, "Cannot create parent type: %s\n", ctf_errmsg (ctf_errno (pfp)));
+ exit (1);
+ create_child:
+ fprintf (stderr, "Cannot create child type: %s\n", ctf_errmsg (ctf_errno (cfp)));
+ exit (1);
+}
diff --git a/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.lk b/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.lk
new file mode 100644
index 0000000..4f23d14
--- /dev/null
+++ b/libctf/testsuite/libctf-writable/pptrtab-writable-page-deep-lookup.lk
@@ -0,0 +1,2 @@
+Type lookup succeeded.
+