* grub-core/io/bufio.c (grub_bufio_read): Fix handling of corner cases.
This commit is contained in:
parent
bbc47747ad
commit
cc4fddf5f5
2 changed files with 22 additions and 22 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2011-12-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* grub-core/io/bufio.c (grub_bufio_read): Fix handling of corner cases.
|
||||||
|
|
||||||
2011-12-25 Vladimir Serbinenko <phcoder@gmail.com>
|
2011-12-25 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* docs/grub.texi (Filesystems): Mention AFS.
|
* docs/grub.texi (Filesystems): Mention AFS.
|
||||||
|
|
|
@ -107,7 +107,9 @@ static grub_ssize_t
|
||||||
grub_bufio_read (grub_file_t file, char *buf, grub_size_t len)
|
grub_bufio_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
{
|
{
|
||||||
grub_size_t res = 0;
|
grub_size_t res = 0;
|
||||||
|
grub_off_t next_buf;
|
||||||
grub_bufio_t bufio = file->data;
|
grub_bufio_t bufio = file->data;
|
||||||
|
grub_ssize_t really_read;
|
||||||
|
|
||||||
if (file->size == GRUB_FILE_SIZE_UNKNOWN)
|
if (file->size == GRUB_FILE_SIZE_UNKNOWN)
|
||||||
file->size = bufio->file->size;
|
file->size = bufio->file->size;
|
||||||
|
@ -130,22 +132,19 @@ grub_bufio_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
|
|
||||||
buf += n;
|
buf += n;
|
||||||
}
|
}
|
||||||
if (! len)
|
if (len == 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* Need to read some more. */
|
/* Need to read some more. */
|
||||||
bufio->buffer_at = grub_divmod64 (file->offset + res + len, bufio->block_size,
|
next_buf = (file->offset + res + len - 1) & ~((grub_off_t) bufio->block_size - 1);
|
||||||
0) * bufio->block_size;
|
|
||||||
|
|
||||||
/* Now read between file->offset + res and bufio->buffer_at. */
|
/* Now read between file->offset + res and bufio->buffer_at. */
|
||||||
if (file->offset + res < bufio->buffer_at)
|
if (file->offset + res < next_buf)
|
||||||
{
|
{
|
||||||
grub_size_t read_now;
|
grub_size_t read_now;
|
||||||
grub_ssize_t really_read;
|
read_now = next_buf - (file->offset + res);
|
||||||
read_now = bufio->buffer_at - (file->offset + res);
|
|
||||||
grub_file_seek (bufio->file, file->offset + res);
|
grub_file_seek (bufio->file, file->offset + res);
|
||||||
really_read = grub_file_read (bufio->file, buf, read_now);
|
really_read = grub_file_read (bufio->file, buf, read_now);
|
||||||
if (grub_errno)
|
if (really_read < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (file->size == GRUB_FILE_SIZE_UNKNOWN)
|
if (file->size == GRUB_FILE_SIZE_UNKNOWN)
|
||||||
file->size = bufio->file->size;
|
file->size = bufio->file->size;
|
||||||
|
@ -168,24 +167,21 @@ grub_bufio_read (grub_file_t file, char *buf, grub_size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read into buffer. */
|
/* Read into buffer. */
|
||||||
grub_file_seek (bufio->file, bufio->buffer_at);
|
grub_file_seek (bufio->file, next_buf);
|
||||||
bufio->buffer_len = grub_file_read (bufio->file, bufio->buffer,
|
really_read = grub_file_read (bufio->file, bufio->buffer,
|
||||||
bufio->block_size);
|
bufio->block_size);
|
||||||
if (grub_errno)
|
if (really_read < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
bufio->buffer_at = next_buf;
|
||||||
|
bufio->buffer_len = really_read;
|
||||||
|
|
||||||
if (file->size == GRUB_FILE_SIZE_UNKNOWN)
|
if (file->size == GRUB_FILE_SIZE_UNKNOWN)
|
||||||
file->size = bufio->file->size;
|
file->size = bufio->file->size;
|
||||||
|
|
||||||
if (len < bufio->buffer_len)
|
if (len > bufio->buffer_len)
|
||||||
{
|
len = bufio->buffer_len;
|
||||||
grub_memcpy (buf, &bufio->buffer[0], len);
|
grub_memcpy (buf, &bufio->buffer[file->offset + res - next_buf], len);
|
||||||
res += len;
|
res += len;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
grub_memcpy (buf, &bufio->buffer[0], bufio->buffer_len);
|
|
||||||
res += bufio->buffer_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue