libcdio-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Libcdio-devel] Invalid/bad directory errors with openSUSE Leap 15.0


From: Thomas Schmitt
Subject: Re: [Libcdio-devel] Invalid/bad directory errors with openSUSE Leap 15.0 ISO
Date: Sat, 26 May 2018 23:49:34 +0200

Hi,

Pete Batard wrote:
> Wouldn't we want to have some logic to discard the big endian value and
> instead use the endian-swapped little endian value if we find that little
> and big endian are in disagreement?

That's how others do it, indeed.

In libcdio's implementation we have the problem that the 8 byte array
is submitted as uint64_t. Its content stems from mapping a struct over
an array of uint8_t.
In lib/iso9660/iso9660_fs.c , _fs_stat_traverse() we have:

 uint8_t *_dirbuf = NULL;
 ...
 while (offset < (_root->secsize * ISO_BLOCKSIZE))
  {
    iso9660_dir_t *p_iso9660_dir = (void *) &_dirbuf[offset];
   
So we'd need to back-map to uint8_t array in from_733*() before we pick
the little-endian value. Like:

  uint8_t *u;
  u = (uint8_t *) p;
  return (u[0] | (u[1] << 8) | (u[2] << 16) | (u[3] << 24));

It might be best to do this unconditionally instead of

  return (UINT32_C(0xFFFFFFFF) & p);

which in my eyes is daringly smart. :))

-----------------------------------------------------------------------

I looked at the sources of the neighboring ISO 9660 readers.
Both return the little-endiang value unconditionally.

At least in Linux, ignorance towards potential conflicts is a feature.
  https://github.com/torvalds/linux/blob/master/fs/isofs/isofs.h
line 105 ff.:

  static inline unsigned int isonum_733(char *p)
  {
          /* Ignore bigendian datum due to broken mastering programs */
          return get_unaligned_le32(p);
  }

libisofs can compare both values if a pointer to a receiving error indicator
is submitted. No protest messages get emitted by the function.
All calls to this function submit error == NULL. So no testing happens
in the current implementation of libisofs.

  uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error)
  {
      uint32_t v1 = iso_read_lsb(buf, bytes);

      if (error) {
          uint32_t v2 = iso_read_msb(buf + bytes, bytes);
          if (v1 != v2)
              *error = 1;
      }
      return v1;
  }


Have a nice day :)

Thomas




reply via email to

[Prev in Thread] Current Thread [Next in Thread]