/* rescoff.c -- read and write resources in Windows COFF files.
- Copyright 1997-2013 Free Software Foundation, Inc.
+ Copyright (C) 1997-2019 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
Rewritten by Kai Tietz, Onevision.
}
set_windres_bfd (&wrbfd, abfd, sec, WR_KIND_BFD);
- size = bfd_section_size (abfd, sec);
- data = (bfd_byte *) res_alloc (size);
+ size = bfd_section_size (sec);
+ /* PR 17512: file: 1b25ba5d
+ The call to get_file_size here may be expensive
+ but there is no other way to determine if the section size
+ is reasonable. */
+ if (size > (bfd_size_type) get_file_size (filename))
+ fatal (_("%s: .rsrc section is bigger than the file!"), filename);
+ data = (bfd_byte *) res_alloc (size);
get_windres_bfd_content (&wrbfd, data, 0, size);
flaginfo.filename = filename;
flaginfo.data = data;
flaginfo.data_end = data + size;
- flaginfo.secaddr = (bfd_get_section_vma (abfd, sec)
- - pe_data (abfd)->pe_opthdr.ImageBase);
+ flaginfo.secaddr = (bfd_section_vma (sec)
+ - pe_data (abfd)->pe_opthdr.ImageBase);
/* Now just read in the top level resource directory. Note that we
don't free data, since we create resource entries that point into
this will have to be cleaned up. */
ret = read_coff_res_dir (&wrbfd, data, &flaginfo, (const rc_res_id *) NULL, 0);
-
+
bfd_close (abfd);
return ret;
rc_res_entry **pp;
const struct extern_res_entry *ere;
+ /* PR 17512: file: 09d80f53.
+ Whilst in theory resources can nest to any level, in practice
+ Microsoft only defines 3 levels. Corrupt files however might
+ claim to use more. */
+ if (level > 4)
+ overrun (flaginfo, _("Resources nest too deep"));
+
if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_directory))
overrun (flaginfo, _("directory"));
re->id.u.n.length = length;
re->id.u.n.name = (unichar *) res_alloc (length * sizeof (unichar));
for (j = 0; j < length; j++)
- re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
+ {
+ /* PR 17512: file: 05dc4a16. */
+ if (length < 0 || ers >= flaginfo->data_end || ers + j * 2 + 4 >= flaginfo->data_end)
+ overrun (flaginfo, _("resource name"));
+ re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
+ }
if (level == 0)
type = &re->id;
+ cwi.dataentsize
+ cwi.resources.length);
- if (! bfd_set_section_size (abfd, sec, length))
+ if (!bfd_set_section_size (sec, length))
bfd_fatal ("bfd_set_section_size");
bfd_set_reloc (abfd, sec, cwi.relocs, cwi.reloc_count);