Repository: PyWavelets/pywt (language: python)

Issue:
DWT hangs with 'reflect' and 'antirefelct' mode on input size 1
In `reflect` and `antireflect` mode, the edges are extended by reflecting the signal as per [documentation](https://pywavelets.readthedocs.io/en/latest/ref/signal-extension-modes.html):

```
... x3 x2 | x1 x2 ... xn | xn-1 xn-2 ...
```
Problem is when the input is of length `1`. There is no `x2`/`xn-1` and effectively the code computing the extending  elements enters an infinite loop. 

## Steps to reproduce:
```python
import pywt
cA, cD = pywt.dwt([1], 'db1', 'reflect')  #<= Will hang in infinite loop
```

## Expected result
Raise a `ValueError` or `IndexError` to report unsupported length

## Actual result
Code enters infinite loop


Discussion / hints:

Fix patch:
diff --git a/pywt/_extensions/_dwt.pyx b/pywt/_extensions/_dwt.pyx
index 9851f0381..0fba4291d 100644
--- a/pywt/_extensions/_dwt.pyx
+++ b/pywt/_extensions/_dwt.pyx
@@ -31,6 +31,9 @@ cpdef dwt_single(cdata_t[::1] data, Wavelet wavelet, MODE mode):
     if output_len < 1:
         raise RuntimeError("Invalid output length.")
 
+    if data_size == 1 and (mode == MODE.MODE_REFLECT or mode == MODE.MODE_ANTIREFLECT):
+        raise ValueError("Input data length must be greater than 1 for [anti]reflect mode.")
+
     if cdata_t is np.float64_t:
         # TODO: Don't think these have to be 0-initialized
         # TODO: Check other methods of allocating (e.g. Cython/CPython arrays)
@@ -87,6 +90,10 @@ cpdef dwt_axis(np.ndarray data, Wavelet wavelet, MODE mode, unsigned int axis=0)
     cdef size_t[::1] input_shape, output_shape
     cdef int retval = -5
 
+
+    if data.shape[axis] == 1 and (mode == MODE.MODE_REFLECT or mode == MODE.MODE_ANTIREFLECT):
+        raise ValueError("Input data length must be greater than 1 for [anti]reflect mode along the transformed axis.")
+
     data = data.astype(_check_dtype(data), copy=False)
 
     input_shape = <size_t [:data.ndim]> <size_t *> data.shape


Test patch:
diff --git a/pywt/tests/test_dwt_idwt.py b/pywt/tests/test_dwt_idwt.py
index 7e9e206bf..4d3922df8 100644
--- a/pywt/tests/test_dwt_idwt.py
+++ b/pywt/tests/test_dwt_idwt.py
@@ -180,6 +180,11 @@ def test_idwt_single_axis():
     assert_allclose(x[0], x0)
     assert_allclose(x[1], x1)
 
+def test_dwt_invalid_input():
+    x = np.arange(1)
+    assert_raises(ValueError, pywt.dwt, x, 'db2', 'reflect')
+    assert_raises(ValueError, pywt.dwt, x, 'haar', 'antireflect')
+
 
 def test_dwt_axis_arg():
     x = [[3, 7, 1, 1],
@@ -191,6 +196,9 @@ def test_dwt_axis_arg():
     assert_allclose(cA_, cA)
     assert_allclose(cD_, cD)
 
+def test_dwt_axis_invalid_input():  
+    x = np.ones((3,1))
+    assert_raises(ValueError, pywt.dwt, x, 'db2', 'reflect')
 
 def test_idwt_axis_arg():
     x = [[3, 7, 1, 1],