Commits

Brian Kearns  committed 66d1e56

prevent streamio SEEK_SET from trashing the buffers for in-buffer seeks, fixes issue1234

  • Participants
  • Parent commits bca3a13

Comments (0)

Files changed (2)

File rpython/rlib/streamio.py

         # This may fail on the do_seek() or do_tell() call.
         # But it won't call either on a relative forward seek.
         # Nor on a seek to the very end.
-        if whence == 0:
-            self.do_seek(offset, 0)
-            self.buf = ""
-            self.pos = 0
-            return
-        if whence == 1:
+        if whence == 0 or whence == 1:
             currentsize = len(self.buf) - self.pos
-            if offset < 0:
-                if self.pos + offset >= 0:
-                    self.pos += offset
-                else:
-                    self.do_seek(self.tell() + offset, 0)
-                    self.pos = 0
-                    self.buf = ""
-                return
-            elif offset <= currentsize:
-                self.pos += offset
+            if whence == 0:
+                difpos = offset - self.tell()
+            else:
+                difpos = offset
+            if -self.pos <= difpos <= currentsize:
+                self.pos += difpos
                 return
             self.buf = ""
             self.pos = 0
-            offset -= currentsize
+            if whence == 1:
+                offset -= currentsize
             try:
-                self.do_seek(offset, 1)
+                self.do_seek(offset, whence)
             except MyNotImplementedError:
+                if difpos < 0:
+                    raise
+                if whence == 0:
+                    offset = difpos - currentsize
                 intoffset = offset2int(offset)
                 self.read(intoffset)
             return

File rpython/rlib/test/test_streamio.py

         end = len(all)
         cases = [(readto, seekto, whence) for readto in range(0, end+1)
                                           for seekto in range(0, end+1)
-                                          for whence in [1, 2]]
+                                          for whence in [0, 1, 2]]
         random.shuffle(cases)
         if isinstance(self, (LLRtypeMixin, OORtypeMixin)):
             cases = cases[:7]      # pick some cases at random - too slow!
                 file = streamio.BufferingInputStream(base)
                 head = file.read(readto)
                 assert head == all[:readto]
-                offset = 42 # for the flow space
                 if whence == 1:
                     offset = seekto - readto
                 elif whence == 2:
                     offset = seekto - end
+                else:
+                    offset = seekto
                 if whence == 2 and seekto < file.tell() or seekto < file.tell() - file.pos:
                     try:
                         file.seek(offset, whence)
                     except streamio.MyNotImplementedError:
-                        assert whence == 1
+                        assert whence in (0, 1)
                     except streamio.StreamError:
                         assert whence == 2
                     else: