<commit_before>#include "mupdf/pdf.h"

#undef DEBUG_PROGESSIVE_ADVANCE

#ifdef DEBUG_PROGESSIVE_ADVANCE
#define DEBUGMESS(A) do { fz_warn A; } while (0)
#else
#define DEBUGMESS(A) do { } while (0)
#endif

static inline int iswhite(int ch)
{
	return
		ch == '\000' || ch == '\011' || ch == '\012' ||
		ch == '\014' || ch == '\015' || ch == '\040';
}

/*
 * xref tables
 */

static void pdf_free_xref_sections(pdf_document *doc)
{
	fz_context *ctx = doc->ctx;
	int x, e;

	for (x = 0; x < doc->num_xref_sections; x++)
	{
		pdf_xref *xref = &doc->xref_sections[x];

		for (e = 0; e < xref->len; e++)
		{
			pdf_xref_entry *entry = &xref->table[e];

			if (entry->obj)
			{
				pdf_drop_obj(entry->obj);
				fz_drop_buffer(ctx, entry->stm_buf);
			}
		}

		fz_free(ctx, xref->table);
		pdf_drop_obj(xref->trailer);
	}

	fz_free(ctx, doc->xref_sections);
	doc->xref_sections = NULL;
	doc->num_xref_sections = 0;
}

static void pdf_resize_xref(fz_context *ctx, pdf_xref *xref, int newlen)
{
	int i;

	xref->table = fz_resize_array(ctx, xref->table, newlen, sizeof(pdf_xref_entry));
	for (i = xref->len; i < newlen; i++)
	{
		xref->table[i].type = 0;
		xref->table[i].ofs = 0;
		xref->table[i].gen = 0;
		xref->table[i].stm_ofs = 0;
		xref->table[i].stm_buf = NULL;
		xref->table[i].obj = NULL;
	}
	xref->len = newlen;
}

static void pdf_populate_next_xref_level(pdf_document *doc)
{
	pdf_xref *xref;
	doc->xref_sections = fz_resize_array(doc->ctx, doc->xref_sections, doc->num_xref_sections + 1, sizeof(pdf_xref));
	doc->num_xref_sections++;

	xref = &doc->xref_sections[doc->num_xref_sections - 1];
	xref->len = 0;
	xref->table = NULL;
	xref->trailer = NULL;
}

pdf_obj *pdf_trailer(pdf_document *doc)
{
	/* Return the document's final trailer */
	pdf_xref *xref = &doc->xref_sections[0];

	return xref->trailer;
}

void pdf_set_populating_xref_trailer(pdf_document *doc, pdf_obj *trailer)
{
	/* Update the trailer of the xref section being populated */
	pdf_xref *xref = &doc->xref_sections[doc->num_xref_sections - 1];
	pdf_drop_obj(xref->trailer);
	xref->trailer = pdf_keep_obj(trailer);
}

int pdf_xref_len(pdf_document *doc)
{
	/* Return the length of the document's final xref section */
	pdf_xref *xref = &doc->xref_sections[0];

	return xref->len;
}

/* Used while reading the individual xref sections from a file */
pdf_xref_entry *pdf_get_populating_xref_entry(pdf_document *doc, int num)
{
	/* Return an entry within the xref currently being populated */
	pdf_xref *xref;
	int i;

	if (doc->num_xref_sections == 0)
	{
		doc->xref_sections = fz_calloc(doc->ctx, 1, sizeof(pdf_xref));
		doc->num_xref_sections = 1;
	}

	/* Prevent accidental heap underflow */
	if (num < 0)
		fz_throw(doc->ctx, FZ_ERROR_GENERIC, "object number must not be negative (%d)", num);

	/* Ensure all xref sections map this entry */
	for (i = doc->num_xref_sections - 1; i >= 0; i--)
	{
		xref = &doc->xref_sections[i];

		if (num >= xref->len)
			pdf_resize_xref(doc->ctx, xref, num+1);
		else
			break; /* Remaining sections already of sufficient size */<commit_msg>Bug 694653: Watch for xref being NULL in pdf_xref_len<commit_after>#include "mupdf/pdf.h"

#undef DEBUG_PROGESSIVE_ADVANCE

#ifdef DEBUG_PROGESSIVE_ADVANCE
#define DEBUGMESS(A) do { fz_warn A; } while (0)
#else
#define DEBUGMESS(A) do { } while (0)
#endif

static inline int iswhite(int ch)
{
	return
		ch == '\000' || ch == '\011' || ch == '\012' ||
		ch == '\014' || ch == '\015' || ch == '\040';
}

/*
 * xref tables
 */

static void pdf_free_xref_sections(pdf_document *doc)
{
	fz_context *ctx = doc->ctx;
	int x, e;

	for (x = 0; x < doc->num_xref_sections; x++)
	{
		pdf_xref *xref = &doc->xref_sections[x];

		for (e = 0; e < xref->len; e++)
		{
			pdf_xref_entry *entry = &xref->table[e];

			if (entry->obj)
			{
				pdf_drop_obj(entry->obj);
				fz_drop_buffer(ctx, entry->stm_buf);
			}
		}

		fz_free(ctx, xref->table);
		pdf_drop_obj(xref->trailer);
	}

	fz_free(ctx, doc->xref_sections);
	doc->xref_sections = NULL;
	doc->num_xref_sections = 0;
}

static void pdf_resize_xref(fz_context *ctx, pdf_xref *xref, int newlen)
{
	int i;

	xref->table = fz_resize_array(ctx, xref->table, newlen, sizeof(pdf_xref_entry));
	for (i = xref->len; i < newlen; i++)
	{
		xref->table[i].type = 0;
		xref->table[i].ofs = 0;
		xref->table[i].gen = 0;
		xref->table[i].stm_ofs = 0;
		xref->table[i].stm_buf = NULL;
		xref->table[i].obj = NULL;
	}
	xref->len = newlen;
}

static void pdf_populate_next_xref_level(pdf_document *doc)
{
	pdf_xref *xref;
	doc->xref_sections = fz_resize_array(doc->ctx, doc->xref_sections, doc->num_xref_sections + 1, sizeof(pdf_xref));
	doc->num_xref_sections++;

	xref = &doc->xref_sections[doc->num_xref_sections - 1];
	xref->len = 0;
	xref->table = NULL;
	xref->trailer = NULL;
}

pdf_obj *pdf_trailer(pdf_document *doc)
{
	/* Return the document's final trailer */
	pdf_xref *xref = &doc->xref_sections[0];

	return xref->trailer;
}

void pdf_set_populating_xref_trailer(pdf_document *doc, pdf_obj *trailer)
{
	/* Update the trailer of the xref section being populated */
	pdf_xref *xref = &doc->xref_sections[doc->num_xref_sections - 1];
	pdf_drop_obj(xref->trailer);
	xref->trailer = pdf_keep_obj(trailer);
}

int pdf_xref_len(pdf_document *doc)
{
	/* Return the length of the document's final xref section */
	pdf_xref *xref = &doc->xref_sections[0];

	return xref == NULL ? 0 : xref->len;
}

/* Used while reading the individual xref sections from a file */
pdf_xref_entry *pdf_get_populating_xref_entry(pdf_document *doc, int num)
{
	/* Return an entry within the xref currently being populated */
	pdf_xref *xref;
	int i;

	if (doc->num_xref_sections == 0)
	{
		doc->xref_sections = fz_calloc(doc->ctx, 1, sizeof(pdf_xref));
		doc->num_xref_sections = 1;
	}

	/* Prevent accidental heap underflow */
	if (num < 0)
		fz_throw(doc->ctx, FZ_ERROR_GENERIC, "object number must not be negative (%d)", num);

	/* Ensure all xref sections map this entry */
	for (i = doc->num_xref_sections - 1; i >= 0; i--)
	{
		xref = &doc->xref_sections[i];

		if (num >= xref->len)
			pdf_resize_xref(doc->ctx, xref, num+1);
		else
			break; /* Remaining sections already of sufficient size */
{'fraction_non_alphanumeric': 0.15770667532889393, 'fraction_numerical': 0.014130258242650642, 'mean_word_length': 4.110373443983402, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 107, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4401460', 'n_tokens_mistral': 2719, 'n_tokens_neox': 2526, 'n_words': 559}