Repository: shapely/shapely

Issue:
segmentation fault using float("nan") in parallel_offset 
## Expected behavior and actual behavior.
Using a nan as a parallel_offset causes a segmentation fault.

Expected the function to return e.g. a ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type (as happens if you pass a string "nan")

## Steps to reproduce the problem.

from shapely.geometry import shape
shape({"type": "LineString", "coordinates": [[0,0],[0,1]]}).parallel_offset(float("nan"))

## Operating system

Linux 

## Shapely version and provenance

1.8.2 installed form pypi using pip

Discussion:
coveralls: ## Pull Request Test Coverage Report for [Build 2975711931](https://coveralls.io/builds/52152939)

* **5** of **5**   **(100.0%)**  changed or added relevant lines in **2** files are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage increased (+**0.02%**) to **85.865%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/52152939/badge)](https://coveralls.io/builds/52152939) |
| :-- | --: |
| Change from base [Build 2878254665](https://coveralls.io/builds/51745917): |  0.02% |
| Covered Lines: | 3019 |
| Relevant Lines: | 3516 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/shapely/geometry/base.py b/shapely/geometry/base.py
index 0a5b053..74a2da4 100644
--- a/shapely/geometry/base.py
+++ b/shapely/geometry/base.py
@@ -622,6 +622,8 @@ class BaseGeometry:
         if mitre_limit == 0.0:
             raise ValueError(
                 'Cannot compute offset from zero-length line segment')
+        elif not math.isfinite(distance):
+            raise ValueError("buffer distance must be finite")
 
         if 'buffer_with_params' in self.impl:
             params = self._lgeos.GEOSBufferParams_create()
diff --git a/shapely/geometry/linestring.py b/shapely/geometry/linestring.py
index 9a4ede8..13484f4 100644
--- a/shapely/geometry/linestring.py
+++ b/shapely/geometry/linestring.py
@@ -2,6 +2,7 @@
 """
 
 from ctypes import c_double
+import math
 import warnings
 
 from shapely.coords import CoordinateSequence
@@ -171,6 +172,8 @@ class LineString(BaseGeometry):
         if mitre_limit == 0.0:
             raise ValueError(
                 'Cannot compute offset from zero-length line segment')
+        elif not math.isfinite(distance):
+            raise ValueError("parallel_offset distance must be finite")
         try:
             return geom_factory(self.impl['parallel_offset'](
                 self, distance, resolution, join_style, mitre_limit, side))


Test patch:
diff --git a/tests/test_buffer.py b/tests/test_buffer.py
index 0e83530..6fd8478 100644
--- a/tests/test_buffer.py
+++ b/tests/test_buffer.py
@@ -1,7 +1,16 @@
+import pytest
+
 from . import unittest
 from shapely import geometry
 
 
+@pytest.mark.parametrize("distance", [float("nan"), float("inf")])
+def test_non_finite_distance(distance):
+    g = geometry.Point(0, 0)
+    with pytest.raises(ValueError, match="distance must be finite"):
+        g.buffer(distance)
+
+
 class BufferSingleSidedCase(unittest.TestCase):
     """ Test Buffer Point/Line/Polygon with and without single_sided params """
 
diff --git a/tests/test_parallel_offset.py b/tests/test_parallel_offset.py
index 661291a..09f3834 100644
--- a/tests/test_parallel_offset.py
+++ b/tests/test_parallel_offset.py
@@ -1,6 +1,15 @@
+import pytest
+
 from . import unittest
 from shapely.geometry import LineString, LinearRing
-from shapely.wkt import loads
+
+
+@pytest.mark.parametrize("distance", [float("nan"), float("inf")])
+def test_non_finite_distance(distance):
+    g = LineString([(0, 0), (10, 0)])
+    with pytest.raises(ValueError, match="distance must be finite"):
+        g.parallel_offset(distance)
+
 
 class OperationsTestCase(unittest.TestCase):