Libxml2Parser.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 /*
10  * The ESI Libxml2 parser is Copyright (c) 2004 by Joachim Bauch
11  * http://www.joachim-bauch.de
12  * mail@joachim-bauch.de
13  */
14 
15 #include "squid.h"
16 
17 #if USE_SQUID_ESI && HAVE_LIBXML2
18 
19 #include "base/RunnersRegistry.h"
20 #include "esi/Libxml2Parser.h"
21 
22 #include <memory>
23 
24 namespace Esi
25 {
26 
27 class Libxml2Rr : public RegisteredRunner
28 {
29 public:
30  void finalizeConfig()
31  {
32  registration.reset(new ESIParser::Register("libxml2", &ESILibxml2Parser::NewParser));
33  }
34 
35 private:
36  std::unique_ptr<ESIParser::Register> registration;
37 };
38 
39 RunnerRegistrationEntry(Libxml2Rr);
40 
41 }
42 
43 // the global document that will store the resolved entity
44 // definitions
45 static htmlDocPtr entity_doc = nullptr;
46 
47 EsiParserDefinition(ESILibxml2Parser);
48 
49 // the SAX callback functions
50 static void
51 esi_startElementSAXFunc(void * ctx, const xmlChar * name, const xmlChar ** atts)
52 {
53  int count=0;
54  xmlChar **tmp = (xmlChar **)atts;
55 
56  while (tmp && *tmp != nullptr) {
57  ++count;
58  ++tmp;
59  }
60 
61  // we increased on every key and value
62  count /= 2;
63 
64  ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
65 
66  p->getClient()->start((const char *)name, (const char **)atts, count);
67 }
68 
69 static void
70 esi_endElementSAXFunc(void *ctx, const xmlChar *name)
71 {
72  ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
73  p->getClient()->end((const char *)name);
74 }
75 
76 static void
77 esi_commentSAXFunc(void *ctx, const xmlChar *value)
78 {
79  ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
80  p->getClient()->parserComment((const char *)value);
81 }
82 
83 static void
84 esi_charactersSAXFunc(void *ctx, const xmlChar *ch, int len)
85 {
86  ESILibxml2Parser *p = (ESILibxml2Parser *)ctx;
87  p->getClient()->parserDefault((const char *)ch, len);
88 }
89 
90 static xmlEntityPtr
91 esi_getEntitySAXFunc(void * /* ctx */, const xmlChar *name)
92 {
93  xmlEntityPtr res = xmlGetDocEntity(entity_doc, name);
94 
95  if (res == nullptr) {
96  const htmlEntityDesc *ent = htmlEntityLookup(name);
97 
98  if (ent != nullptr) {
99  char tmp[32];
100  snprintf(tmp, 32, "&#%d;", ent->value);
101  res = xmlAddDocEntity(entity_doc, (const xmlChar *)name, XML_INTERNAL_GENERAL_ENTITY, nullptr, nullptr, (const xmlChar *)tmp);
102  }
103  }
104 
105  return res;
106 }
107 
108 ESILibxml2Parser::ESILibxml2Parser(ESIParserClient *aClient) : theClient (aClient)
109 {
110  xmlSAXHandler sax;
111  htmlDefaultSAXHandlerInit();
112  memset(&sax, 0, sizeof(sax));
113  sax.startElement = esi_startElementSAXFunc;
114  sax.endElement = esi_endElementSAXFunc;
115  sax.comment = esi_commentSAXFunc;
116  sax.characters = esi_charactersSAXFunc;
117  sax.getEntity = esi_getEntitySAXFunc;
118 
119  /* TODO: grab the document encoding from the headers */
120  parser = xmlCreatePushParserCtxt(&sax, static_cast<void *>(this), nullptr, 0, nullptr);
121 
122  if (entity_doc == nullptr)
123  entity_doc = htmlNewDoc(nullptr, nullptr);
124 }
125 
126 ESILibxml2Parser::~ESILibxml2Parser()
127 {
128  xmlFreeParserCtxt(parser);
129  parser = nullptr;
130 }
131 
132 bool
133 ESILibxml2Parser::parse(char const *dataToParse, size_t const lengthOfData, bool const endOfStream)
134 {
135  return (xmlParseChunk(parser, dataToParse, lengthOfData, endOfStream) == 0);
136 }
137 
138 long int
139 ESILibxml2Parser::lineNumber() const
140 {
141  return (long int)xmlSAX2GetLineNumber(parser);
142 }
143 
144 char const *
145 ESILibxml2Parser::errorString() const
146 {
147  xmlErrorPtr error = xmlGetLastError();
148 
149  if (error == nullptr)
150  return nullptr;
151 
152  return error->message;
153 }
154 
155 #endif /* USE_SQUID_ESI */
156 
#define RunnerRegistrationEntry(Who)
convenience macro: register one RegisteredRunner kid as early as possible
void error(char *format,...)
#define EsiParserDefinition(ThisClass)
Definition: Parser.h:64
ESI protocol types and operators.
Definition: Element.h:89
static struct node * parse(FILE *fp)
Definition: parse.c:965

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors