Repository: py-pdf/pypdf (Python)

Issue:
Unexpected escaped string for a valid PDF.
Given the PDF available at: https://export.arxiv.org/pdf/1707.04066v1
the current snippet:
```python
import PyPDF2
pdf = PyPDF2.PdfFileReader("/tmp/1707.04066v1")
pdf.getNamedDestinations()
```
will crash with:
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/pdf.py", line 1312, in getNamedDestinations
    self.getNamedDestinations(kid.getObject(), retval)
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/generic.py", line 178, in getObject
    return self.pdf.getObject(self).getObject()
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/pdf.py", line 1611, in getObject
    retval = readObject(self.stream, self)
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/generic.py", line 66, in readObject
    return DictionaryObject.readFromStream(stream, pdf)
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/generic.py", line 579, in readFromStream
    value = readObject(stream, pdf)
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/generic.py", line 71, in readObject
    return ArrayObject.readFromStream(stream, pdf)
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/generic.py", line 166, in readFromStream
    arr.append(readObject(stream, pdf))
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/generic.py", line 77, in readObject
    return readStringFromStream(stream)
  File "/home/skaplun/.virtualenvs/labs3/local/lib/python2.7/site-packages/PyPDF2/generic.py", line 390, in readStringFromStream
    raise utils.PdfReadError(r"Unexpected escaped string: %s" % tok)
PyPDF2.utils.PdfReadError: Unexpected escaped string: h
```

This is with the latest stable release available on PyPI and the latest master


Discussion:
I can confirm with `PyPDF2==1.27.7`:

```
Traceback (most recent call last):
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/generic.py", line 381, in readStringFromStream
    tok = ESCAPE_DICT[tok]
KeyError: b'h'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "issue459.py", line 3, in <module>
    pdf.getNamedDestinations()
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/pdf.py", line 1436, in getNamedDestinations
    self.getNamedDestinations(kid.getObject(), retval)
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/generic.py", line 191, in getObject
    return self.pdf.getObject(self).getObject()
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/pdf.py", line 1739, in getObject
    retval = readObject(self.stream, self)
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/generic.py", line 79, in readObject
    return DictionaryObject.readFromStream(stream, pdf)
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/generic.py", line 602, in readFromStream
    value = readObject(stream, pdf)
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/generic.py", line 84, in readObject
    return ArrayObject.readFromStream(stream, pdf)
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/generic.py", line 181, in readFromStream
    arr.append(readObject(stream, pdf))
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/generic.py", line 90, in readObject
    return readStringFromStream(stream)
  File "/home/moose/Github/py-pdf/PyPDF2/PyPDF2/generic.py", line 407, in readStringFromStream
    raise PdfReadError(r"Unexpected escaped string: %s" % tok)
PyPDF2.errors.PdfReadError: Unexpected escaped string: b'h'
```



Patch:
diff --git a/PyPDF2/generic.py b/PyPDF2/generic.py
index c78fcdff7f..f175439bf0 100644
--- a/PyPDF2/generic.py
+++ b/PyPDF2/generic.py
@@ -422,9 +422,9 @@ def readStringFromStream(stream):
                     # line break was escaped:
                     tok = b_("")
                 else:
-                    raise PdfReadError(
-                        r"Unexpected escaped string: {}".format(tok.decode("utf8"))
-                    )
+                    msg = r"Unexpected escaped string: {}".format(tok.decode("utf8"))
+                    # if.strict: PdfReadError(msg)
+                    logger.warning(msg)
         txt += tok
     return createStringObject(txt)
 


Test patch:
diff --git a/Tests/test_generic.py b/Tests/test_generic.py
index a7cc014287..b1b43dcf6e 100644
--- a/Tests/test_generic.py
+++ b/Tests/test_generic.py
@@ -113,7 +113,8 @@ def test_readStringFromStream_not_in_escapedict_no_digit():
     stream = BytesIO(b"x\\y")
     with pytest.raises(PdfReadError) as exc:
         readStringFromStream(stream)
-    assert exc.value.args[0] == "Unexpected escaped string: y"
+    assert exc.value.args[0] == "Stream has ended unexpectedly"
+    # "Unexpected escaped string: y"
 
 
 def test_readStringFromStream_multichar_eol():
@@ -216,6 +217,11 @@ def test_DictionaryObject_key_is_no_pdfobject():
     assert exc.value.args[0] == "key must be PdfObject"
 
 
+def test_DictionaryObject_xmp_meta():
+    do = DictionaryObject({NameObject("/S"): NameObject("/GoTo")})
+    assert do.xmpMetadata is None
+
+
 def test_DictionaryObject_value_is_no_pdfobject():
     do = DictionaryObject({NameObject("/S"): NameObject("/GoTo")})
     with pytest.raises(ValueError) as exc:
@@ -237,6 +243,11 @@ def test_DictionaryObject_setdefault_value_is_no_pdfobject():
     assert exc.value.args[0] == "value must be PdfObject"
 
 
+def test_DictionaryObject_setdefault_value():
+    do = DictionaryObject({NameObject("/S"): NameObject("/GoTo")})
+    do.setdefault(NameObject("/S"), NameObject("/GoTo"))
+
+
 def test_DictionaryObject_read_from_stream():
     stream = BytesIO(b"<< /S /GoTo >>")
     pdf = None