Jelajahi Sumber

Fix segfaults when parsing python term arguments.

Stefano Cossu 2 tahun lalu
induk
melakukan
70116fad13
3 mengubah file dengan 50 tambahan dan 31 penghapusan
  1. 36 4
      cpython/py_term.h
  2. 13 26
      cpython/py_triple.h
  3. 1 1
      setup.py

+ 36 - 4
cpython/py_term.h

@@ -29,10 +29,15 @@ Term_init (TermObject *self, PyObject *args, PyObject *kwargs)
             &term_type, &data, &datatype, &lang))
         return -1;
 
-    char *metadata = datatype ? datatype : lang;
-
-    self->ob_struct = LSUP_term_new (
-            (LSUP_TermType) term_type, data, metadata);
+    if (datatype) {
+        LSUP_Term *dtype_uri = LSUP_term_new (
+                LSUP_TERM_IRIREF, datatype, NULL);
+        self->ob_struct = LSUP_term_new (
+                (LSUP_TermType) term_type, data, dtype_uri);
+    } else {
+        self->ob_struct = LSUP_term_new (
+                (LSUP_TermType) term_type, data, lang);
+    }
     if (!self->ob_struct) {
         PyErr_SetString (PyExc_ValueError, "Could not create term.");
         return -1;
@@ -381,5 +386,32 @@ Term_richcmp (PyObject *obj1, PyObject *obj2, int op)
     return result;
  }
 
+
+PyObject *
+build_term (LSUP_Term *t)
+{
+    log_trace ("Building term: %s", t->data);
+    char *datatype = (
+            t->type == LSUP_TERM_LITERAL && t->datatype ?
+            t->datatype->data : NULL);
+    char *lang = (
+            t->type == LSUP_TERM_LT_LITERAL && strlen (t->lang) ?
+            t->lang : NULL);
+    PyObject *term_args = Py_BuildValue (
+            "bszz", t->type, t->data, datatype, lang);
+    if (UNLIKELY (!term_args)) {
+        PyErr_SetString (PyExc_ValueError, "Invalid object args.");
+        return NULL;
+    }
+    PyObject *t_obj = PyObject_CallObject ((PyObject *)&TermType, term_args);
+    Py_DECREF (term_args);
+    if (UNLIKELY (!t_obj)) {
+        PyErr_SetString (PyExc_ValueError, "Invalid object.");
+        return NULL;
+    }
+
+    return t_obj;
+}
+
 // END _PY_TERM_OBJ_H
 #endif

+ 13 - 26
cpython/py_triple.h

@@ -120,33 +120,20 @@ PyTypeObject TripleType = {
 PyObject *
 build_triple (LSUP_Triple *spo)
 {
-    PyObject *s_obj, *p_obj, *o_obj, *spo_obj, *term_args, *trp_args;
-
-    term_args = Py_BuildValue (
-            "bszz", spo->s->type, spo->s->data,
-            spo->s->datatype, spo->s->lang);
-    s_obj = PyObject_CallObject ((PyObject *)&TermType, term_args);
-    Py_DECREF (term_args);
-    if (UNLIKELY (!s_obj)) return NULL;
-
-    term_args = Py_BuildValue (
-            "bszz", spo->p->type, spo->p->data,
-            spo->p->datatype, spo->p->lang);
-    p_obj = PyObject_CallObject ((PyObject *)&TermType, term_args);
-    if (UNLIKELY (!p_obj)) return NULL;
-    Py_DECREF (term_args);
-
-    term_args = Py_BuildValue (
-            "bszz", spo->o->type, spo->o->data,
-            spo->o->datatype, spo->o->lang);
-    o_obj = PyObject_CallObject ((PyObject *)&TermType, term_args);
-    if (UNLIKELY (!o_obj)) return NULL;
-    Py_DECREF (term_args);
-
-    trp_args = Py_BuildValue ("OOO", s_obj, p_obj, o_obj);
-    spo_obj = PyObject_CallObject ((PyObject *)&TripleType, trp_args);
-    if (UNLIKELY (!spo_obj)) return NULL;
+    log_info ("Building triple.");
+    PyObject *trp_args = Py_BuildValue (
+            "OOO",
+            build_term (spo->s), build_term (spo->p), build_term (spo->o));
+    if (UNLIKELY (!trp_args)) {
+        PyErr_SetString (PyExc_SystemError, "Error building triple args.");
+        return NULL;
+    }
+    PyObject *spo_obj = PyObject_CallObject ((PyObject *)&TripleType, trp_args);
     Py_DECREF (trp_args);
+    if (UNLIKELY (!spo_obj)) {
+        PyErr_SetString (PyExc_SystemError, "Error building triple object.");
+        return NULL;
+    }
 
     return spo_obj;
 }

+ 1 - 1
setup.py

@@ -55,7 +55,7 @@ if debug:
     print("Compiling with debug flags.")
     compile_args.extend([
         "-UNDEBUG", "-U_FORTIFY_SOURCE",
-        "-DDEBUG", "-g3", "-O0"
+        "-DDEBUG", "-g3", "-O1"
     ])
 else:
     compile_args.extend(["-g0", "-O3"])