archive/iso9660: fix odd seeking bug (assertion failure)
Skip the beginning of a sector if the last seek was odd, and clear the buffer on seek.
This commit is contained in:
parent
5acea014b0
commit
79b2366387
|
@ -182,10 +182,21 @@ class Iso9660InputStream final : public InputStream {
|
||||||
fill = nbytes;
|
fill = nbytes;
|
||||||
position = 0;
|
position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clear() noexcept {
|
||||||
|
position = fill = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BlockBuffer buffer;
|
BlockBuffer buffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Skip this number of bytes of the first sector after filling
|
||||||
|
* the buffer next time. This is used for seeking into the
|
||||||
|
* middle of a sector.
|
||||||
|
*/
|
||||||
|
size_t skip = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Iso9660InputStream(const std::shared_ptr<Iso9660> &_iso,
|
Iso9660InputStream(const std::shared_ptr<Iso9660> &_iso,
|
||||||
const char *_uri,
|
const char *_uri,
|
||||||
|
@ -208,7 +219,9 @@ public:
|
||||||
if (new_offset > size)
|
if (new_offset > size)
|
||||||
throw std::runtime_error("Invalid seek offset");
|
throw std::runtime_error("Invalid seek offset");
|
||||||
|
|
||||||
offset = new_offset;
|
skip = new_offset % ISO_BLOCKSIZE;
|
||||||
|
offset = new_offset - skip;
|
||||||
|
buffer.Clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -273,9 +286,20 @@ Iso9660InputStream::Read(void *ptr, size_t read_size)
|
||||||
buffer.Append(nbytes);
|
buffer.Append(nbytes);
|
||||||
|
|
||||||
r = buffer.Read();
|
r = buffer.Read();
|
||||||
|
|
||||||
|
if (skip > 0) {
|
||||||
|
if (skip >= r.size)
|
||||||
|
throw std::runtime_error("Premature end of ISO9660 track");
|
||||||
|
|
||||||
|
buffer.Consume(skip);
|
||||||
|
skip = 0;
|
||||||
|
|
||||||
|
r = buffer.Read();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!r.empty());
|
assert(!r.empty());
|
||||||
|
assert(skip == 0);
|
||||||
|
|
||||||
size_t nbytes = std::min(read_size, r.size);
|
size_t nbytes = std::min(read_size, r.size);
|
||||||
memcpy(ptr, r.data, nbytes);
|
memcpy(ptr, r.data, nbytes);
|
||||||
|
|
Loading…
Reference in New Issue