diff --git a/semantica/triplet_store/blazegraph_store.py b/semantica/triplet_store/blazegraph_store.py index 9a18faf3..4e139a57 100644 --- a/semantica/triplet_store/blazegraph_store.py +++ b/semantica/triplet_store/blazegraph_store.py @@ -395,7 +395,8 @@ class BlazegraphStore: if " " in inner or ">" in inner: raise ValueError(f"IRI contains invalid characters: {obj!r}") return obj - return f"<{obj}>" + validated_obj = sparql_escaping.validate_uri(obj) + return f"<{validated_obj}>" escaped = self._escape_literal(obj) datatype = metadata.get("datatype") or metadata.get("literal_datatype") diff --git a/semantica/triplet_store/rdf4j_store.py b/semantica/triplet_store/rdf4j_store.py index cdf05061..594f6dd2 100644 --- a/semantica/triplet_store/rdf4j_store.py +++ b/semantica/triplet_store/rdf4j_store.py @@ -536,7 +536,8 @@ class RDF4JStore: if " " in inner or ">" in inner: raise ValueError(f"IRI contains invalid characters: {obj!r}") return obj - return f"<{obj}>" + validated_obj = sparql_escaping.validate_uri(obj) + return f"<{validated_obj}>" escaped = sparql_escaping.escape_literal(obj) datatype = metadata.get("datatype") or metadata.get("literal_datatype") diff --git a/tests/triplet_store/test_sparql_injection.py b/tests/triplet_store/test_sparql_injection.py index 863efa85..d8bb0e48 100644 --- a/tests/triplet_store/test_sparql_injection.py +++ b/tests/triplet_store/test_sparql_injection.py @@ -17,7 +17,7 @@ before any query/update text is built. """ import unittest -from unittest.mock import MagicMock, patch +from unittest.mock import patch from semantica.semantic_extract.triplet_extractor import Triplet from semantica.triplet_store.blazegraph_store import BlazegraphStore @@ -84,7 +84,8 @@ class TestBlazegraphSparqlInjection(unittest.TestCase): class TestRDF4JSparqlInjection(unittest.TestCase): - def _make_store(self): + @patch.object(RDF4JStore, "_connect", autospec=True) + def _make_store(self, _mock_connect): return RDF4JStore(endpoint="http://localhost:9999/rdf4j", repository_id="mem") def test_triplets_to_ntriples_rejects_malicious_subject(self):