QL-Win/QuickLook · warning · IndexOutOfRangeException

DS_Store: block id out of range

Error message

DS_Store: block id out of range

What it means

Thrown by DSStoreAllocator.GetBlock when a block id (bid) exceeds the number of entries in the _offsets table. The B-tree traversal references a block index that was never recorded during ReadOffsets, indicating a corrupt or inconsistent offset table.

Source

Thrown at QuickLook.Plugin/QuickLook.Plugin.ArchiveViewer/DSStore/DSStoreExtractor.cs:148

                for (int k = 0; k < (int)blkcount; k++)
                    _root.ReadUint32(); // consume entries; not needed for filename extraction
            }
        }

        public List<string> TraverseFromRootNode()
        {
            if (!_toc.TryGetValue("DSDB", out var tocVal))
                return [];
            var rootBlk = GetBlock(tocVal);
            uint rootNode = rootBlk.ReadUint32();
            rootBlk.Skip(4 * 4);
            return Traverse(rootNode);
        }

        internal DSStoreBlock GetBlock(uint bid)
        {
            if (_offsets.Count <= (int)bid)
                throw new IndexOutOfRangeException("DS_Store: block id out of range");
            uint addr   = _offsets[(int)bid];
            int  offset = (int)(addr & ~0x1Fu);
            int  size   = 1 << (int)(addr & 0x1Fu);
            return NewBlock((uint)offset, (uint)size);
        }

        private List<string> Traverse(uint bid)
        {
            var filenames = new List<string>();
            var node = GetBlock(bid);
            uint nextPtr = node.ReadUint32();
            uint count   = node.ReadUint32();

            if (nextPtr > 0)
            {
                for (int i = 0; i < (int)count; i++)
                {
                    uint next = node.ReadUint32();

View on GitHub (pinned to cb5d9c429c)

Solutions

  1. Catch IndexOutOfRangeException around GetFileNames and return filenames collected so far.
  2. Re-copy the .DS_Store from the macOS source.
  3. Validate that the offset-table count in the root block matches expectations before traversal.
  4. Clamp/ignore out-of-range block ids instead of throwing.
Defensive patterns

Strategy: try-catch

Try / catch

try { var names = DSStoreExtractor.GetFileNames(path); }
catch (IndexOutOfRangeException ex) when (ex.Message.Contains("block id out of range"))
{
    // B-tree references a block not in the offset table; return partial results.
    names = new List<string>();
}

Prevention

When it happens

Trigger: During Traverse/TraverseFromRootNode, a node's next-pointer or child pointer yields a bid >= _offsets.Count: corrupt B-tree pointers, a truncated offset table, or a malformed .DS_Store.

Common situations: Corrupt .DS_Store from disk errors or bad transfers; a file from a non-standard writer with a different offset-table layout; truncated file where ReadOffsets did not capture all entries.

Related errors


AI-assisted analysis of QL-Win/QuickLook@cb5d9c429c (2026-08-13). Data as JSON: /api/errors/a7d396ae34cf133d. Report an issue: GitHub.