readelf: Consolidate --syms --use-dynamic with --dyn-syms
[deliverable/binutils-gdb.git] / binutils / resbin.c
index b5dcd9b5f2ce9c19be98001bb57d0b564c0460f7..79d5ffde1f17bf7d9ab05835ba701fe7dee698c8 100644 (file)
@@ -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-2020 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)
     {
This page took 0.030749 seconds and 4 git commands to generate.