From e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 22:34:10 +0200 Subject: Adding upstream version 4.2.2. Signed-off-by: Daniel Baumann --- epan/dtd_preparse.l | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 epan/dtd_preparse.l (limited to 'epan/dtd_preparse.l') diff --git a/epan/dtd_preparse.l b/epan/dtd_preparse.l new file mode 100644 index 0000000..ff8ab14 --- /dev/null +++ b/epan/dtd_preparse.l @@ -0,0 +1,302 @@ +%top { +/* Include this before everything else, for various large-file definitions */ +#include "config.h" +#include +} + +/* + * We want a reentrant scanner. + */ +%option reentrant + +/* + * We don't use input, so don't generate code for it. + */ +%option noinput + +/* + * We don't use unput, so don't generate code for it. + */ +%option nounput + +/* + * We don't read interactively from the terminal. + */ +%option never-interactive + +/* + * We want to stop processing when we get to the end of the input. + */ +%option noyywrap + +/* + * The type for the state we keep for a scanner. + */ +%option extra-type="Dtd_PreParse_scanner_state_t *" + +/* + * The language we're scanning is case-insensitive. + */ +%option caseless + +/* + * Prefix scanner routines with "Dtd_PreParse_" rather than "yy", so this + * scanner can coexist with other scanners. + */ +%option prefix="Dtd_PreParse_" + +%option outfile="dtd_preparse.c" + +/* + * We have to override the memory allocators so that we don't get + * "unused argument" warnings from the yyscanner argument (which + * we don't use, as we have a global memory allocator). + * + * We provide, as macros, our own versions of the routines generated by Flex, + * which just call malloc()/realloc()/free() (as the Flex versions do), + * discarding the extra argument. + */ +%option noyyalloc +%option noyyrealloc +%option noyyfree + +%{ + /* + * dtd_preparse.l + * + * an XML dissector for wireshark + * + * DTD Preparser - import a dtd file into a GString + * including files, removing comments + * and resolving %entities; + * + * Copyright 2004, Luis E. Garcia Ontanon + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include "dtd.h" +#include + +/* + * Disable diagnostics in the code generated by Flex. + */ +DIAG_OFF_FLEX() + +#define ECHO g_string_append(yyextra->current,yytext); + +struct _dtd_preparse_scanner_state { + const gchar* dtd_dirname; + const gchar* filename; + guint linenum; + + GString* error; + + GHashTable* entities; + GString* current; + GString* output; + gchar* entity_name; +}; + +static const gchar* replace_entity(Dtd_PreParse_scanner_state_t* state, gchar* s); + +#define YY_USER_INIT { \ + BEGIN OUTSIDE; \ +} + +/* + * Flex (v 2.5.35) uses this symbol to "exclude" unistd.h + */ +#ifdef _WIN32 +#define YY_NO_UNISTD_H +#endif + +/* + * Sleazy hack to suppress compiler warnings in yy_fatal_error(). + */ +#define YY_EXIT_FAILURE ((void)yyscanner, 2) + +/* + * Macros for the allocators, to discard the extra argument. + */ +#define Dtd_PreParse_alloc(size, yyscanner) (void *)malloc(size) +#define Dtd_PreParse_realloc(ptr, size, yyscanner) (void *)realloc((char *)(ptr), (size)) +#define Dtd_PreParse_free(ptr, yyscanner) free((char *)ptr) + +%} +xmlpi_start "" +xmlpi_chars . + +comment_start "" +special_start "" + +entity_start "current) g_string_append_printf(yyextra->current,"%s\n%s\n",replace_entity(yyextra, yytext),dtd_location(yyextra)); + +{whitespace} if (yyextra->current) g_string_append(yyextra->current," "); + +{xmlpi_start} { g_string_append(yyextra->current,yytext); BEGIN XMLPI; } +{xmlpi_chars} { g_string_append(yyextra->current,yytext); } +{newline} { g_string_append(yyextra->current,yytext); } +{xmlpi_stop} { g_string_append(yyextra->current,yytext); BEGIN OUTSIDE; } + +{comment_start} { yyextra->current = NULL; BEGIN IN_COMMENT; } +[^-]? | +[-] ; +{comment_stop} { yyextra->current = yyextra->output; BEGIN OUTSIDE; } + +{newline} { + yyextra->linenum++; + if (yyextra->current) g_string_append_printf(yyextra->current,"%s\n",dtd_location(yyextra)); +} + + +{entity_start} { BEGIN IN_ENTITY; } +{name} { yyextra->entity_name = ws_strdup_printf("%%%s;",yytext); BEGIN NAMED_ENTITY; } +{quote} { yyextra->current = g_string_new(dtd_location(yyextra)); BEGIN IN_QUOTE; } +{quote} { g_hash_table_insert(yyextra->entities,yyextra->entity_name,yyextra->current); BEGIN ENTITY_DONE; } +{percent} | +{non_quote} | +{escaped_quote} g_string_append(yyextra->current,yytext); +{system} { + g_string_append_printf(yyextra->error,"at %s:%u: file inclusion is not supported!", yyextra->filename, yyextra->linenum); + yyterminate(); +} +{special_stop} { yyextra->current = yyextra->output; g_string_append(yyextra->current,"\n"); BEGIN OUTSIDE; } + +%% + +/* + * Turn diagnostics back on, so we check the code that we've written. + */ +DIAG_ON_FLEX() + +static const gchar* replace_entity(Dtd_PreParse_scanner_state_t* state, gchar* entity) { + GString* replacement; + + *entity = '%'; + + replacement = (GString*)g_hash_table_lookup(state->entities,entity); + + if (replacement) { + return replacement->str; + } else { + g_string_append_printf(state->error,"dtd_preparse: in file '%s': entity %s does not exists\n", state->filename, entity); + return ""; + } + +} + +const gchar* dtd_location(Dtd_PreParse_scanner_state_t* state) { + static gchar* loc = NULL; + + g_free(loc); + + if (!state) return NULL; + + loc = ws_strdup_printf("", state->filename, state->linenum); + + return loc; +} + +static gboolean free_gstring_hash_items(gpointer k,gpointer v,gpointer p _U_) { + g_free(k); + g_string_free((GString*)v,TRUE); + return TRUE; +} + +extern GString* dtd_preparse(const gchar* dname,const gchar* fname, GString* err) { + gchar* fullname = ws_strdup_printf("%s%c%s",dname,G_DIR_SEPARATOR,fname); + FILE *in; + yyscan_t scanner; + Dtd_PreParse_scanner_state_t state; + + in = ws_fopen(fullname,"r"); + + if (!in) { + if (err) + g_string_append_printf(err, "Could not open file: '%s', error: %s",fullname,g_strerror(errno)); + g_free(fullname); + return NULL; + } + + if (Dtd_PreParse_lex_init(&scanner) != 0) { + if (err) + g_string_append_printf(err, "Can't initialize scanner: %s", + strerror(errno)); + fclose(in); + g_free(fullname); + return NULL; + } + + Dtd_PreParse_set_in(in, scanner); + + state.dtd_dirname = dname; + state.filename = fname; + state.linenum = 1; + + state.error = err; + + state.entities = g_hash_table_new(g_str_hash,g_str_equal); + state.current = state.output = g_string_new(dtd_location(&state)); + state.entity_name = NULL; + + /* Associate the state with the scanner */ + Dtd_PreParse_set_extra(&state, scanner); + + Dtd_PreParse_lex(scanner); + + Dtd_PreParse_lex_destroy(scanner); + fclose(in); + + g_hash_table_foreach_remove(state.entities,free_gstring_hash_items,NULL); + g_hash_table_destroy(state.entities); + + g_free(fullname); + + return state.output; +} -- cgit v1.2.3