Fix handling of tar numbers occupying the whole field.

* grub-core/fs/cpio.c (read_number): New function.
	(grub_cpio_find_file): Use read_number instead of strtoull.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-12-23 14:11:31 +01:00
parent a54a0e1270
commit 58eba9eec7
2 changed files with 21 additions and 5 deletions

View file

@ -1,3 +1,10 @@
2011-12-23 Vladimir Serbinenko <phcoder@gmail.com>
Fix handling of tar numbers occupying the whole field.
* grub-core/fs/cpio.c (read_number): New function.
(grub_cpio_find_file): Use read_number instead of strtoull.
2011-12-23 Vladimir Serbinenko <phcoder@gmail.com> 2011-12-23 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/cpio.c (grub_cpio_find_file): Fix handling of names * grub-core/fs/cpio.c (grub_cpio_find_file): Fix handling of names

View file

@ -108,6 +108,15 @@ canonicalize (char *name)
*optr = 0; *optr = 0;
} }
static inline unsigned long long
read_number (const char *str, grub_size_t size)
{
long long ret = 0;
while (size-- && *str >= '0' && *str <= '7')
ret = (ret << 3) | (*str++ & ~'0');
return ret;
}
static grub_err_t static grub_err_t
grub_cpio_find_file (struct grub_cpio_data *data, char **name, grub_cpio_find_file (struct grub_cpio_data *data, char **name,
grub_int32_t *mtime, grub_disk_addr_t *ofs, grub_int32_t *mtime, grub_disk_addr_t *ofs,
@ -178,7 +187,7 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
if (hd.typeflag == 'L') if (hd.typeflag == 'L')
{ {
grub_err_t err; grub_err_t err;
grub_size_t namesize = grub_strtoull (hd.size, NULL, 8); grub_size_t namesize = read_number (hd.size, sizeof (hd.size));
*name = grub_malloc (namesize + 1); *name = grub_malloc (namesize + 1);
if (*name == NULL) if (*name == NULL)
return grub_errno; return grub_errno;
@ -198,7 +207,7 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
if (hd.typeflag == 'K') if (hd.typeflag == 'K')
{ {
grub_err_t err; grub_err_t err;
grub_size_t linksize = grub_strtoull (hd.size, NULL, 8); grub_size_t linksize = read_number (hd.size, sizeof (hd.size));
if (data->linkname_alloc < linksize + 1) if (data->linkname_alloc < linksize + 1)
{ {
char *n; char *n;
@ -230,15 +239,15 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name,
return grub_errno; return grub_errno;
} }
data->size = grub_strtoull (hd.size, NULL, 8); data->size = read_number (hd.size, sizeof (hd.size));
data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE; data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
*ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) & *ofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
~(GRUB_DISK_SECTOR_SIZE - 1)); ~(GRUB_DISK_SECTOR_SIZE - 1));
if (mtime) if (mtime)
*mtime = grub_strtoul (hd.mtime, NULL, 8); *mtime = read_number (hd.mtime, sizeof (hd.mtime));
if (mode) if (mode)
{ {
*mode = grub_strtoul (hd.mode, NULL, 8); *mode = read_number (hd.mode, sizeof (hd.mode));
switch (hd.typeflag) switch (hd.typeflag)
{ {
case '2': case '2':