diff options
| author | Sebastian Wüst <sebi@timewaster.de> | 2013-10-20 15:32:08 +0000 |
|---|---|---|
| committer | Sebastian Wüst <sebi@timewaster.de> | 2013-10-20 15:32:08 +0000 |
| commit | 82908f949129e1fcbf62002799ee7b1b77986eed (patch) | |
| tree | c02098dd7720cdf424f2793ecd3ddac2ea86b969 /src/xml | |
| parent | changed text (diff) | |
| parent | Fix build errors with clang 3.3 and c++11 enabled. (diff) | |
| download | inkscape-82908f949129e1fcbf62002799ee7b1b77986eed.tar.gz inkscape-82908f949129e1fcbf62002799ee7b1b77986eed.zip | |
merge from trunk
(bzr r12417.1.24)
Diffstat (limited to 'src/xml')
| -rw-r--r-- | src/xml/quote-test.h | 5 | ||||
| -rw-r--r-- | src/xml/quote.cpp | 12 | ||||
| -rw-r--r-- | src/xml/quote.h | 3 | ||||
| -rw-r--r-- | src/xml/repr-io.cpp | 111 | ||||
| -rw-r--r-- | src/xml/repr-util.cpp | 4 |
5 files changed, 97 insertions, 38 deletions
diff --git a/src/xml/quote-test.h b/src/xml/quote-test.h index bd5c1f54c..bc01ec4e9 100644 --- a/src/xml/quote-test.h +++ b/src/xml/quote-test.h @@ -7,10 +7,7 @@ #include <cstring> #include <functional> -/* mental disclaims all responsibility for this evil idea for testing - static functions. The main disadvantages are that we retain any - #define's and `using' directives of the included file. */ -#include "quote.cpp" +#include "quote.h" class XmlQuoteTest : public CxxTest::TestSuite { diff --git a/src/xml/quote.cpp b/src/xml/quote.cpp index 030a6c764..c9e001d05 100644 --- a/src/xml/quote.cpp +++ b/src/xml/quote.cpp @@ -19,7 +19,7 @@ /** \return strlen(xml_quote_strdup(\a val)) (without doing the malloc). * \pre val != NULL */ -static size_t +size_t xml_quoted_strlen(char const *val) { size_t ret = 0; @@ -43,11 +43,11 @@ xml_quoted_strlen(char const *val) static void xml_quote(char *dest, char const *src) { -#define COPY_LIT(_lit) do { \ - size_t cpylen = sizeof(_lit "") - 1; \ - memcpy(dest, _lit, cpylen); \ - dest += cpylen; \ - } while(0) +#define COPY_LIT(_lit) do { \ + size_t cpylen = sizeof(_lit "") - 1; \ + memcpy(dest, _lit, cpylen); \ + dest += cpylen; \ + } while(0) for (; *src != '\0'; ++src) { switch (*src) { diff --git a/src/xml/quote.h b/src/xml/quote.h index 597272cd3..8e3bca0eb 100644 --- a/src/xml/quote.h +++ b/src/xml/quote.h @@ -1,6 +1,9 @@ #ifndef SEEN_XML_QUOTE_H #define SEEN_XML_QUOTE_H +#include <stddef.h> + +size_t xml_quoted_strlen(char const *val); char *xml_quote_strdup(char const *src); diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp index 1b6116936..54eff00bc 100644 --- a/src/xml/repr-io.cpp +++ b/src/xml/repr-io.cpp @@ -78,11 +78,14 @@ public: XmlSource() : filename(0), encoding(0), - fp(0), + fp(NULL), firstFewLen(0), + LoadEntities(false), + cachedData(), + cachedPos(0), dummy("x"), - instr(0), - gzin(0) + instr(NULL), + gzin(NULL) { for (int k=0;k<4;k++) { @@ -98,7 +101,9 @@ public: } } - int setFile( char const * filename ); + int setFile( char const * filename, bool load_entities ); + + xmlDocPtr readXml(); static int readCb( void * context, char * buffer, int len ); static int closeCb( void * context ); @@ -112,12 +117,15 @@ private: FILE* fp; unsigned char firstFew[4]; int firstFewLen; + bool LoadEntities; // Checks for SYSTEM Entities (requires cached data) + std::string cachedData; + unsigned int cachedPos; Inkscape::URI dummy; Inkscape::IO::UriInputStream* instr; Inkscape::IO::GzipInputStream* gzin; }; -int XmlSource::setFile(char const *filename) +int XmlSource::setFile(char const *filename, bool load_entities=false) { int retVal = -1; @@ -174,14 +182,62 @@ int XmlSource::setFile(char const *filename) retVal = 0; // no error } } + if(load_entities) { + this->cachedData = std::string(""); + this->cachedPos = 0; + + // First get data from file in typical way (cache it all) + char *buffer = new char [4096]; + while(true) { + int len = this->read(buffer, 4096); + if(len <= 0) break; + buffer[len] = 0; + this->cachedData += buffer; + } + delete[] buffer; + + // Check for SYSTEM or PUBLIC entities and remove them from the cache + GMatchInfo *info; + gint start, end; + + GRegex *regex = g_regex_new( + "<!ENTITY\\s+[^>\\s]+\\s+(SYSTEM|PUBLIC\\s+\"[^>\"]+\")\\s+\"[^>\"]+\"\\s*>", + G_REGEX_CASELESS, G_REGEX_MATCH_NEWLINE_ANY, NULL); + + g_regex_match (regex, this->cachedData.c_str(), G_REGEX_MATCH_NEWLINE_ANY, &info); + while (g_match_info_matches (info)) { + if (g_match_info_fetch_pos (info, 1, &start, &end)) + this->cachedData.erase(start, end - start); + g_match_info_next (info, NULL); + } + g_match_info_free(info); + g_regex_unref(regex); + } + // Do this after loading cache, so reads don't return cache to fill cache. + this->LoadEntities = load_entities; return retVal; } +xmlDocPtr XmlSource::readXml() +{ + int parse_options = XML_PARSE_HUGE | XML_PARSE_RECOVER; + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool allowNetAccess = prefs->getBool("/options/externalresources/xml/allow_net_access", false); + if (!allowNetAccess) parse_options |= XML_PARSE_NONET; + + // Allow NOENT only if we're filtering out SYSTEM and PUBLIC entities + if (LoadEntities) parse_options |= XML_PARSE_NOENT; + + return xmlReadIO( readCb, closeCb, this, + filename, getEncoding(), parse_options); +} int XmlSource::readCb( void * context, char * buffer, int len ) { int retVal = -1; + if ( context ) { XmlSource* self = static_cast<XmlSource*>(context); retVal = self->read( buffer, len ); @@ -203,7 +259,15 @@ int XmlSource::read( char *buffer, int len ) int retVal = 0; size_t got = 0; - if ( firstFewLen > 0 ) { + if ( LoadEntities ) { + if (cachedPos >= cachedData.length()) { + return -1; + } else { + retVal = cachedData.copy(buffer, len, cachedPos); + cachedPos += retVal; + return retVal; // Do NOT continue. + } + } else if ( firstFewLen > 0 ) { int some = (len < firstFewLen) ? len : firstFewLen; memcpy( buffer, firstFew, some ); if ( len < firstFewLen ) { @@ -299,22 +363,20 @@ Document *sp_repr_read_file (const gchar * filename, const gchar *default_ns) XmlSource src; if ( (src.setFile(filename) == 0) ) { - int parse_options = XML_PARSE_HUGE; // do not use XML_PARSE_NOENT ! see bug lp:1025185 - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool allowNetAccess = prefs->getBool("/options/externalresources/xml/allow_net_access", false); - if (!allowNetAccess) { - parse_options |= XML_PARSE_NONET; + doc = src.readXml(); + rdoc = sp_repr_do_read( doc, default_ns ); + // For some reason, failed ns loading results in this + // We try a system check version of load with NOENT for adobe + if(rdoc && strcmp(rdoc->root()->name(), "ns:svg") == 0) { + xmlFreeDoc( doc ); + src.setFile(filename, true); + doc = src.readXml(); + rdoc = sp_repr_do_read( doc, default_ns ); } - doc = xmlReadIO( XmlSource::readCb, - XmlSource::closeCb, - &src, - localFilename, - src.getEncoding(), - parse_options); } } - rdoc = sp_repr_do_read( doc, default_ns ); + if ( doc ) { xmlFreeDoc( doc ); } @@ -504,7 +566,6 @@ gint sp_repr_qualified_name (gchar *p, gint len, xmlNsPtr ns, const xmlChar *nam static Node *sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gchar *default_ns, GHashTable *prefix_map) { - Node *repr, *crepr; xmlAttrPtr prop; xmlNodePtr child; gchar c[256]; @@ -544,7 +605,7 @@ static Node *sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gc } sp_repr_qualified_name (c, 256, node->ns, node->name, default_ns, prefix_map); - repr = xml_doc->createElement(c); + Node *repr = xml_doc->createElement(c); /* TODO remember node->ns->prefix if node->ns != NULL */ for (prop = node->properties; prop != NULL; prop = prop->next) { @@ -561,7 +622,7 @@ static Node *sp_repr_svg_read_node (Document *xml_doc, xmlNodePtr node, const gc child = node->xmlChildrenNode; for (child = node->xmlChildrenNode; child != NULL; child = child->next) { - crepr = sp_repr_svg_read_node (xml_doc, child, default_ns, prefix_map); + Node *crepr = sp_repr_svg_read_node (xml_doc, child, default_ns, prefix_map); if (crepr) { repr->appendChild(crepr); Inkscape::GC::release(crepr); @@ -948,15 +1009,15 @@ void sp_repr_write_stream_element( Node * repr, Writer & out, // THIS DOESN'T APPEAR TO DO ANYTHING. Can it be commented out or deleted? { GQuark const href_key = g_quark_from_static_string("xlink:href"); - GQuark const absref_key = g_quark_from_static_string("sodipodi:absref"); + //GQuark const absref_key = g_quark_from_static_string("sodipodi:absref"); gchar const *xxHref = 0; - gchar const *xxAbsref = 0; + //gchar const *xxAbsref = 0; for ( List<AttributeRecord const> ai(attributes); ai; ++ai ) { if ( ai->key == href_key ) { xxHref = ai->value; - } else if ( ai->key == absref_key ) { - xxAbsref = ai->value; + //} else if ( ai->key == absref_key ) { + //xxAbsref = ai->value; } } diff --git a/src/xml/repr-util.cpp b/src/xml/repr-util.cpp index 8c8425de0..12280ea5a 100644 --- a/src/xml/repr-util.cpp +++ b/src/xml/repr-util.cpp @@ -432,13 +432,11 @@ unsigned int sp_repr_get_int(Inkscape::XML::Node *repr, gchar const *key, int *v unsigned int sp_repr_get_double(Inkscape::XML::Node *repr, gchar const *key, double *val) { - gchar const *v; - g_return_val_if_fail(repr != NULL, FALSE); g_return_val_if_fail(key != NULL, FALSE); g_return_val_if_fail(val != NULL, FALSE); - v = repr->attribute(key); + gchar const *v = repr->attribute(key); if (v != NULL) { *val = g_ascii_strtod(v, NULL); |
