Repository: obspy/obspy

Issue:
Infinite loop when trying to read full SEED file without any mini SEED records
When trying to read a full SEED file without any mini SEED records, while specifying input format MSEED, the code runs into an infinite loop.

Example file (contained FSEED file): http://webservices.ingv.it/webservices/ingv_ws_data/data/view_waveform_at_ingv.it/2015/08/24/093006_1594696/1594696_data.tgz

Code to reproduce:
```
import obspy
obspy.read('1594696_data/1594696_data.fseed', 'MSEED')
```

Code gets stuck searching for first data record, in the following loop:
https://github.com/obspy/obspy/blob/6d6d20c7c35126b18de5d33af962aa1c51dbfdd7/obspy/io/mseed/util.py#L646

I suppose the problem could be fixed with a check if EOF has been reached. For intended behavior I'm unsure if an exception should be raise or rather if just an empty Stream object should be returned.

<!--

**GitHub should mainly be used for bug reports and code developments/discussions. For generic questions, please use either the [[obspy-users] mailing list](http://lists.swapbytes.de/mailman/listinfo/obspy-users) (for scientific questions to the general ObsPy community) or our [gitter chat](https://gitter.im/obspy/obspy) (for technical questions and direct contact to the developers).**

Before submitting an Issue, please review the [Issue Guidelines](https://github.com/obspy/obspy/blob/master/CONTRIBUTING.md#submitting-an-issue).

-->

ObsPy version: 1.1.0 (installed through pip in a conda virtual env)
Python version: 3.6.5
OS: Ubuntu 18.04


Discussion:

Resolving patch:
diff --git a/obspy/io/mseed/util.py b/obspy/io/mseed/util.py
--- a/obspy/io/mseed/util.py
+++ b/obspy/io/mseed/util.py
@@ -643,7 +643,15 @@ def _get_record_information(file_object, offset=0, endian=None):
         # reset file pointer
         file_object.seek(record_start, 0)
         # cycle through file using record length until first data record found
-        while file_object.read(7)[6:7] not in [b'D', b'R', b'Q', b'M']:
+        while True:
+            data = file_object.read(7)[6:7]
+            if data in [b'D', b'R', b'Q', b'M']:
+                break
+            # stop looking when hitting end of file
+            # the second check should be enough.. but play it safe
+            if not data or record_start > info['filesize']:
+                msg = "No MiniSEED data record found in file."
+                raise ValueError(msg)
             record_start += rec_len
             file_object.seek(record_start, 0)
 


Test patch:
diff --git a/obspy/io/mseed/tests/test_mseed_util.py b/obspy/io/mseed/tests/test_mseed_util.py
--- a/obspy/io/mseed/tests/test_mseed_util.py
+++ b/obspy/io/mseed/tests/test_mseed_util.py
@@ -1324,6 +1324,21 @@ def test_get_record_information_with_invalid_word_order(self):
             'number_of_records': 1,
             'excess_bytes': 0})
 
+    def test_read_fullseed_no_data_record(self):
+        # see 2534
+        filename = os.path.join(self.path, 'data',
+                                'RJOB.BW.EHZ.D.300806.0000.fullseed')
+        # file contains two records, the second being the miniseed record.
+        # make a bytes buffer without the data record
+        with open(filename, 'rb') as fh:
+            data = fh.read()
+        buf = io.BytesIO(data[:512])  # only first record
+        buf.seek(0)
+        with self.assertRaises(ValueError) as e:
+            _read_mseed(buf)
+        self.assertEqual(
+            str(e.exception), "No MiniSEED data record found in file.")
+
 
 def suite():
     return unittest.makeSuite(MSEEDUtilTestCase, 'test')