/* resbin.c -- manipulate the Windows binary resource format.
- Copyright 1997, 1998, 1999, 2002, 2003, 2005, 2006, 2007, 2009, 2010, 2011
- Free Software Foundation, Inc.
+ Copyright (C) 1997-2019 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
Rewritten by Kai Tietz, Onevision.
dc->data = NULL;
else
{
- off = (off + 3) &~ 3;
-
if (length < off + datalen)
toosmall (_("dialog control data"));
if (length < 8)
toosmall (key);
- *len = windres_get_16 (wrbfd, data, 2);
+ *len = (windres_get_16 (wrbfd, data, 2) + 3) & ~3;
*vallen = windres_get_16 (wrbfd, data + 2, 2);
*type = windres_get_16 (wrbfd, data + 4, 2);
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);
data += off;
length -= off;
- /* It's convenient to round verlen to a 4 byte alignment,
- since we round the subvariables in the loop. */
-
- verlen = (verlen + 3) &~ 3;
+ verlen -= off;
vi->u.string.stringtables = NULL;
ppvst = &vi->u.string.stringtables;
length -= off;
verlen -= off;
- stverlen = (stverlen + 3) &~ 3;
-
+ stverlen -= off;
+
vst->strings = NULL;
ppvs = &vst->strings;
get_version_header (wrbfd, data, length, (const char *) NULL,
&vs->key, &sverlen, &vallen, &type, &off);
- sverlen = (sverlen + 3) &~ 3;
-
data += off;
length -= off;
vs->value = get_unicode (wrbfd, data, length, &vslen);
valoff = vslen * 2 + 2;
- valoff = (valoff + 3) &~ 3;
+ valoff = (valoff + 3) & ~3;
if (off + valoff != sverlen)
fatal (_("unexpected version string length %ld != %ld + %ld"),
fatal (_("unexpected version string length %ld < %ld"),
(long) verlen, (long) sverlen);
stverlen -= sverlen;
+ verlen -= sverlen;
vs->next = NULL;
*ppvs = vs;
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;
if (wrbfd)
{
struct bin_res_id bri;
-
+
windres_put_16 (wrbfd, bri.sig, 0xffff);
windres_put_16 (wrbfd, bri.id, id.u.id);
set_windres_bfd_content (wrbfd, &bri, off, BIN_RES_ID);
windres_put_32 (wrbfd, bdc.id, dc->id);
set_windres_bfd_content (wrbfd, &bdc, off, BIN_DIALOGEX_CONTROL_SIZE);
}
- }
+ }
off += (dialogex != 0 ? BIN_DIALOGEX_CONTROL_SIZE : BIN_DIALOG_CONTROL_SIZE);
off = resid_to_bin (wrbfd, off, dc->class);
{
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)
{