<commit_before>/*
 * Copyright 2012 Red Hat Inc., Durham, North Carolina.
 * All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors:
 *      <NAME> <<EMAIL>>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "public/scap_ds.h"
#include "common/list.h"
#include "common/_error.h"
#include "common/alloc.h"
#include "common/elements.h"

#include <libxml/xmlreader.h>
#include <string.h>

struct ds_stream_index
{
	char* id;
	char* timestamp;
	char* version;

	struct oscap_stringlist* check_components;
	struct oscap_stringlist* checklist_components;
	struct oscap_stringlist* dictionary_components;
	struct oscap_stringlist* extended_components;
};

struct ds_stream_index* ds_stream_index_new(void)
{
	struct ds_stream_index* ret = oscap_alloc(sizeof(struct ds_stream_index));

	ret->id = NULL;
	ret->timestamp = NULL;
	ret->version = NULL;

	ret->check_components = oscap_stringlist_new();
	ret->checklist_components = oscap_stringlist_new();
	ret->dictionary_components = oscap_stringlist_new();
	ret->extended_components = oscap_stringlist_new();

	return ret;
}

void ds_stream_index_free(struct ds_stream_index* s)
{
	oscap_free(s->id);
	oscap_free(s->timestamp);
	oscap_free(s->version);

	oscap_stringlist_free(s->check_components);
	oscap_stringlist_free(s->checklist_components);
	oscap_stringlist_free(s->dictionary_components);
	oscap_stringlist_free(s->extended_components);

	oscap_free(s);
}

const char* ds_stream_index_get_id(struct ds_stream_index* s)
{
	return s->id;
}

const char* ds_stream_index_get_timestamp(struct ds_stream_index* s)
{
	return s->timestamp;
}

const char* ds_stream_index_get_version(struct ds_stream_index* s)
{
	return s->version;
}

struct oscap_string_iterator* ds_stream_index_get_checks(struct ds_stream_index* s)
{
	return oscap_iterator_new((struct oscap_list*)s->check_components);
}

struct oscap_string_iterator* ds_stream_index_get_checklists(struct ds_stream_index* s)
{
	return oscap_iterator_new((struct oscap_list*)s->checklist_components);
}

struct oscap_string_iterator* ds_stream_index_get_dictionaries(struct ds_stream_index* s)
{
	return oscap_iterator_new((struct oscap_list*)s->dictionary_components);
}

struct oscap_string_iterator* ds_stream_index_get_extended_components(struct ds_stream_index* s)
{
	return oscap_iterator_new((struct oscap_list*)s->extended_components);
}

static struct ds_stream_index* ds_stream_index_parse(xmlTextReaderPtr reader)
{
	struct ds_stream_index* ret = ds_stream_index_new();

	// sanity check
	if (xmlTextReaderNodeType(reader) != 1 ||
	    strcmp((const char*)xmlTextReaderConstLocalName(reader), "data-stream") != 0)
	{
		oscap_seterr(OSCAP_EFAMILY_XML,
		             "Expected to have xmlTextReader at start of <ds:data-stream>, "
		             "the current event is '%i' at '%s' instead. I refuse to parse!",
		             xmlTextReaderNodeType(reader), (const char*)xmlTextReaderConstLocalName(reader));

		return NULL;
	}

	ret->id = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "id");
	ret->timestamp = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "timestamp");
	ret->version = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "scap-version");

	// We assume well-formedness and validity of the datastream.
	// The parser can be broken with invalid content such as:
	// .. <checklists><checks/><component-ref ../></checklists> ..

	struct oscap_stringlist* cref_target = NULL;
	while (xmlTextReaderRead(reader) == 1)
	{
		int node_type = xmlTextReaderNodeType(reader);
		const char* local_name = (const char*)xmlTextReaderConstLocalName(reader);

		if (node_type == 15 && // 15 == end element
		    strcmp(local_name, "data-stream") == 0)
		{
			// we are done reading
			break;
		}
		// the following code switches where we push component refs<commit_msg>Allocate sds_stream_index only after sanity check has been done<commit_after>/*
 * Copyright 2012 Red Hat Inc., Durham, North Carolina.
 * All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors:
 *      <NAME> <<EMAIL>>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "public/scap_ds.h"
#include "common/list.h"
#include "common/_error.h"
#include "common/alloc.h"
#include "common/elements.h"

#include <libxml/xmlreader.h>
#include <string.h>

struct ds_stream_index
{
	char* id;
	char* timestamp;
	char* version;

	struct oscap_stringlist* check_components;
	struct oscap_stringlist* checklist_components;
	struct oscap_stringlist* dictionary_components;
	struct oscap_stringlist* extended_components;
};

struct ds_stream_index* ds_stream_index_new(void)
{
	struct ds_stream_index* ret = oscap_alloc(sizeof(struct ds_stream_index));

	ret->id = NULL;
	ret->timestamp = NULL;
	ret->version = NULL;

	ret->check_components = oscap_stringlist_new();
	ret->checklist_components = oscap_stringlist_new();
	ret->dictionary_components = oscap_stringlist_new();
	ret->extended_components = oscap_stringlist_new();

	return ret;
}

void ds_stream_index_free(struct ds_stream_index* s)
{
	oscap_free(s->id);
	oscap_free(s->timestamp);
	oscap_free(s->version);

	oscap_stringlist_free(s->check_components);
	oscap_stringlist_free(s->checklist_components);
	oscap_stringlist_free(s->dictionary_components);
	oscap_stringlist_free(s->extended_components);

	oscap_free(s);
}

const char* ds_stream_index_get_id(struct ds_stream_index* s)
{
	return s->id;
}

const char* ds_stream_index_get_timestamp(struct ds_stream_index* s)
{
	return s->timestamp;
}

const char* ds_stream_index_get_version(struct ds_stream_index* s)
{
	return s->version;
}

struct oscap_string_iterator* ds_stream_index_get_checks(struct ds_stream_index* s)
{
	return oscap_iterator_new((struct oscap_list*)s->check_components);
}

struct oscap_string_iterator* ds_stream_index_get_checklists(struct ds_stream_index* s)
{
	return oscap_iterator_new((struct oscap_list*)s->checklist_components);
}

struct oscap_string_iterator* ds_stream_index_get_dictionaries(struct ds_stream_index* s)
{
	return oscap_iterator_new((struct oscap_list*)s->dictionary_components);
}

struct oscap_string_iterator* ds_stream_index_get_extended_components(struct ds_stream_index* s)
{
	return oscap_iterator_new((struct oscap_list*)s->extended_components);
}

static struct ds_stream_index* ds_stream_index_parse(xmlTextReaderPtr reader)
{
	// sanity check
	if (xmlTextReaderNodeType(reader) != 1 ||
	    strcmp((const char*)xmlTextReaderConstLocalName(reader), "data-stream") != 0)
	{
		oscap_seterr(OSCAP_EFAMILY_XML,
		             "Expected to have xmlTextReader at start of <ds:data-stream>, "
		             "the current event is '%i' at '%s' instead. I refuse to parse!",
		             xmlTextReaderNodeType(reader), (const char*)xmlTextReaderConstLocalName(reader));

		return NULL;
	}

	struct ds_stream_index* ret = ds_stream_index_new();

	ret->id = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "id");
	ret->timestamp = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "timestamp");
	ret->version = (char*)xmlTextReaderGetAttribute(reader, BAD_CAST "scap-version");

	// We assume well-formedness and validity of the datastream.
	// The parser can be broken with invalid content such as:
	// .. <checklists><checks/><component-ref ../></checklists> ..

	struct oscap_stringlist* cref_target = NULL;
	while (xmlTextReaderRead(reader) == 1)
	{
		int node_type = xmlTextReaderNodeType(reader);
		const char* local_name = (const char*)xmlTextReaderConstLocalName(reader);

		if (node_type == 15 && // 15 == end element
		    strcmp(local_name, "data-stream") == 0)
		{
			// we are done reading
			break;
		}
		// the following code switches where we push component refs
{'fraction_non_alphanumeric': 0.10288609825952853, 'fraction_numerical': 0.006168759638686935, 'mean_word_length': 5.344514325646401, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 28}, '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': '3348885', 'n_tokens_mistral': 3042, 'n_tokens_neox': 2934, 'n_words': 753}