Here's what happens: - read1 reads the #[] and proceeds to create a vector of zero length - allocate_vectorlike has a special case for zero length vectors: if (len == 0) p = XVECTOR (zero_vector); - zero_vector is a global variable, so all zero length vectors point to it. This can be seen when evalling: (eq [] []) ; Evalutes to t (eq [1 2 3] [1 2 3]) ; Evaluates to nil - After read1 creates the zero_vector, it sets bits in the size field to indicate it is a PVEC_COMPILED pseudo vector - The global zero_vector is thereafter a PVEC_COMPILED pseudo vector, including the empty vector of the font data - Later, the font_list_entities function checks the size of the font data vector using ASIZE. It does not expect a pseudo vector, so it makes no such checks. - Because the pseudo vector bits are set, the size is very large - Indexing too far into the font data vector results in a core dump What should the behavior be? Perhaps (eval #[]) should evaluate to [] instead of #[]? Maybe an eassert in font_list_entities that its vector is not a pseudo vector couldn't hurt either?