{
DSI *dsi = obj->dsi;
struct ofork *ofork;
- off_t offset, saveoff, reqcount, savereqcount;
+ off_t offset, saveoff, reqcount, savereqcount, size;
ssize_t cc, err;
int eid;
uint16_t ofrefnum;
AFP_READ_START((long)reqcount);
+ /* reqcount isn't always truthful. we need to deal with that. */
+ size = ad_size(ofork->of_ad, eid);
+
LOG(log_debug, logtype_afpd,
- "afp_read(fork: %" PRIu16 " [%s], off: %" PRIu64 ", len: %" PRIu64 ")",
- ofork->of_refnum, (ofork->of_flags & AFPFORK_DATA) ? "data" : "reso", offset, reqcount);
+ "afp_read(fork: %" PRIu16 " [%s], off: %" PRIu64 ", len: %" PRIu64 ", size: %" PRIu64 ")",
+ ofork->of_refnum, (ofork->of_flags & AFPFORK_DATA) ? "data" : "reso", offset, reqcount, size);
+
+ if (offset >= size) {
+ err = AFPERR_EOF;
+ goto afp_read_err;
+ }
+
+ /* subtract off the offset */
+ if (reqcount + offset > size) {
+ reqcount = size - offset;
+ err = AFPERR_EOF;
+ }
savereqcount = reqcount;
saveoff = offset;