X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fresbin.c;h=f7b83cfeeebac2db496aeec0f865aab6c7e5a812;hb=9108bc33b1ca0b2e930c0cce5b1a0394e33e86be;hp=b5dcd9b5f2ce9c19be98001bb57d0b564c0460f7;hpb=bfb6c1ab1ed502faa7c3764722a1f1661f6d44e8;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/resbin.c b/binutils/resbin.c index b5dcd9b5f2..f7b83cfeee 100644 --- a/binutils/resbin.c +++ b/binutils/resbin.c @@ -1,6 +1,5 @@ /* 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-2018 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. Rewritten by Kai Tietz, Onevision. @@ -575,8 +574,6 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length dc->data = NULL; else { - off = (off + 3) &~ 3; - if (length < off + datalen) toosmall (_("dialog control data")); @@ -909,7 +906,7 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt 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); @@ -962,9 +959,10 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt 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); @@ -1041,10 +1039,7 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt 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; @@ -1070,8 +1065,8 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt length -= off; verlen -= off; - stverlen = (stverlen + 3) &~ 3; - + stverlen -= off; + vst->strings = NULL; ppvs = &vst->strings; @@ -1088,14 +1083,12 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt 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"), @@ -1108,6 +1101,7 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt fatal (_("unexpected version string length %ld < %ld"), (long) verlen, (long) sverlen); stverlen -= sverlen; + verlen -= sverlen; vs->next = NULL; *ppvs = vs; @@ -1169,8 +1163,15 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt 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; @@ -1323,7 +1324,7 @@ resid_to_bin (windres_bfd *wrbfd, rc_uint_type off, rc_res_id id) 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); @@ -1561,7 +1562,7 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog 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); @@ -1579,7 +1580,6 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog { 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); @@ -1587,10 +1587,10 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog 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) {