diff --git a/python/_re2.cc b/python/_re2.cc index 22f092b2..20d9cfa5 100644 --- a/python/_re2.cc +++ b/python/_re2.cc @@ -38,6 +38,11 @@ namespace py = pybind11; // the py::buffer_info manages a reference count to the py::buffer, so it // must be constructed and subsequently destructed while holding the GIL. static inline absl::string_view FromBytes(const py::buffer_info& bytes) { + if (bytes.ndim != 1 || bytes.itemsize != 1 || bytes.strides.size() != 1 || + bytes.strides[0] != 1) { + throw py::type_error( + "buffer must be a one-dimensional contiguous buffer of bytes"); + } char* data = reinterpret_cast(bytes.ptr); ssize_t size = bytes.size; return absl::string_view(data, size); diff --git a/python/re2_test.py b/python/re2_test.py index 146b55b4..a8884723 100644 --- a/python/re2_test.py +++ b/python/re2_test.py @@ -301,6 +301,19 @@ def test_compile_with_latin1_encoding(self): # ... whereas this is fine, of course. re2.compile(b'.?', options=options) + def test_noncontiguous_buffer_rejected(self): + regexp = re2.compile(b'.') + for text in (memoryview(b'0123456789')[::-1], + memoryview(b'0123456789')[::2]): + with self.assertRaisesRegex( + re2.error, 'one-dimensional contiguous buffer of bytes'): + regexp.search(text) + + for pattern in (memoryview(b'.')[::-1], memoryview(b'..')[::2]): + with self.assertRaisesRegex( + re2.error, 'one-dimensional contiguous buffer of bytes'): + re2.compile(pattern) + @parameterized.parameters( (u'\\p{Lo}', u'\u0ca0_\u0ca0', [(0, 1), (2, 3)]), (b'\\p{Lo}', b'\xe0\xb2\xa0_\xe0\xb2\xa0', [(0, 3), (4, 7)]),