/* resbin.c -- manipulate the Windows binary resource format.
- Copyright (C) 1997-2015 Free Software Foundation, Inc.
+ Copyright (C) 1997-2023 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
Rewritten by Kai Tietz, Onevision.
static rc_res_resource *bin_to_res_group_icon (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_version (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_userdata (windres_bfd *, const bfd_byte *, rc_uint_type);
-static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *, rc_uint_type);
+static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *);
static void get_version_header (windres_bfd *, const bfd_byte *, rc_uint_type, const char *,
unichar **, rc_uint_type *, rc_uint_type *, rc_uint_type *,
rc_uint_type *);
case RT_VERSION:
return bin_to_res_version (wrbfd, data, length);
case RT_TOOLBAR:
- return bin_to_res_toolbar (wrbfd, data, length);
+ return bin_to_res_toolbar (wrbfd, data);
}
}
dc->data = NULL;
else
{
- off = (off + 3) &~ 3;
-
if (length < off + datalen)
toosmall (_("dialog control data"));
get_version_header (wrbfd, data, length, "VS_VERSION_INFO",
(unichar **) NULL, &verlen, &vallen, &type, &off);
- if ((unsigned int) verlen != length)
- fatal (_("version length %d does not match resource length %lu"),
- (int) verlen, (unsigned long) length);
+ /* PR 17512: The verlen field does not include padding length. */
+ if (verlen > length)
+ fatal (_("version length %lu greater than resource length %lu"),
+ (unsigned long) verlen, (unsigned long) length);
if (type != 0)
fatal (_("unexpected version type %d"), (int) type);
+ /* PR 27686: Ignore any padding bytes after the end of the version structure. */
+ length = verlen;
+
data += off;
length -= off;
vallen -= 4;
}
}
+ else if (ch == 0)
+ {
+ if (length == 8)
+ /* Padding - skip. */
+ break;
+ fatal (_("nul bytes found in version string"));
+ }
else
- fatal (_("unexpected version string"));
+ fatal (_("unexpected version string character: %x"), ch);
vi->next = NULL;
*pp = vi;
}
\f
static rc_res_resource *
-bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
+bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data)
{
rc_toolbar *ri;
rc_res_resource *r;
ri->items = NULL;
data += 12;
- length -= 12;
for (i=0 ; i < ri->nitems; i++)
{
rc_toolbar_item *it;
it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
it->prev = it->next = NULL;
data += 4;
- length -= 4;
if(ri->items) {
rc_toolbar_item *ii = ri->items;
while (ii->next != NULL)
{
rc_uint_type saved_off = off;
rc_uint_type old_off;
- off += (4 - ((off - off_delta) & 3)) & 3;
old_off = off;
off = res_to_bin_rcdata (wrbfd, off, dc->data);
old_off = off = saved_off;
if (wrbfd)
windres_put_16 (wrbfd, dc_rclen, off - old_off);
- }
+ }
if (wrbfd)
set_windres_bfd_content (wrbfd, dc_rclen, marker, 2);
- }
+ }
if (wrbfd)
{