https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78665

--- Comment #2 from Richard W.M. Jones <rjones at redhat dot com> ---
The code which calculates seg_len is surely quite interesting in that case:

      size_t seg_len = block_len (h, blkoff, &used);
      if (seg_len <= 4 || (seg_len & 3) != 0) {

The block_len function which is probably inlined is:

static inline size_t
block_len (hive_h *h, size_t blkoff, int *used)
{
  struct ntreg_hbin_block *block;
  block = (struct ntreg_hbin_block *) ((char *) h->addr + blkoff);

  int32_t len = le32toh (block->seg_len);
  if (len < 0) {
    if (used) *used = 1;
    len = -len;
  } else {
    if (used) *used = 0;
  }

  return (size_t) len;
}

The original data format (a Windows NT registry) encodes a 32 bit block
length into every header, and negates this length field if the block is
marked as "used" (it's positive if the block is free).

I can't recall if converting int32_t -> (64 bit) size_t is safe or not.

Reply via email to