summaryrefslogtreecommitdiffstats
path: root/src/xml
diff options
context:
space:
mode:
authorMartin Owens <doctormo@gmail.com>2013-09-13 22:11:56 +0000
committerMartin Owens <doctormo@gmail.com>2013-09-13 22:11:56 +0000
commit68830b1facc049966ecab3c7d2a0106e28c8dea7 (patch)
tree0edfb00afabfb8b742ad7ecd6f78d9f179f3effc /src/xml
parentImprove the functions which create GdkPixbuf from Cairo surface (diff)
downloadinkscape-68830b1facc049966ecab3c7d2a0106e28c8dea7.tar.gz
inkscape-68830b1facc049966ecab3c7d2a0106e28c8dea7.zip
Fix the latest error with the adobe svg ns errors, boundry exceptions caused security failure.
(bzr r12513)
Diffstat (limited to 'src/xml')
-rw-r--r--src/xml/repr-io.cpp82
1 files changed, 49 insertions, 33 deletions
diff --git a/src/xml/repr-io.cpp b/src/xml/repr-io.cpp
index c692e6509..f5a558607 100644
--- a/src/xml/repr-io.cpp
+++ b/src/xml/repr-io.cpp
@@ -98,10 +98,9 @@ public:
}
}
- int setFile( char const * filename );
+ int setFile( char const * filename, bool load_entities );
xmlDocPtr readXml();
- bool SystemCheck; // Checks for SYSTEM Entities
static int readCb( void * context, char * buffer, int len );
static int closeCb( void * context );
@@ -115,16 +114,18 @@ 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;
- this->SystemCheck = false;
this->filename = filename;
fp = Inkscape::IO::fopen_utf8name(filename, "r");
@@ -178,7 +179,40 @@ 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;
+ }
+ free(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_unref(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;
}
@@ -191,7 +225,7 @@ xmlDocPtr XmlSource::readXml()
if (!allowNetAccess) parse_options |= XML_PARSE_NONET;
// Allow NOENT only if we're filtering out SYSTEM and PUBLIC entities
- if (SystemCheck) parse_options |= XML_PARSE_NOENT;
+ if (LoadEntities) parse_options |= XML_PARSE_NOENT;
return xmlReadIO( readCb, closeCb, this,
filename, getEncoding(), parse_options);
@@ -204,31 +238,6 @@ int XmlSource::readCb( void * context, char * buffer, int len )
if ( context ) {
XmlSource* self = static_cast<XmlSource*>(context);
retVal = self->read( buffer, len );
-
- if(self->SystemCheck) {
- 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);
-
- // Check for SYSTEM or PUBLIC entities and kill them with spaces
- // Note: g_regex_replace does not modify buffer in place, this
- // logic is used instead because we can just blank out the offending
- // charicters in the right place without hurting the length.
- g_regex_match (regex, buffer, G_REGEX_MATCH_NEWLINE_ANY, &info);
-
- while (g_match_info_matches (info)) {
- if (g_match_info_fetch_pos (info, 1, &start, &end)) {
- for (int x=start; x<end; x++)
- buffer[x] = 0x20;
- }
- g_match_info_next (info, NULL);
- }
- g_match_info_free(info);
- g_regex_unref(regex);
- }
}
return retVal;
}
@@ -247,7 +256,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 ) {
@@ -349,8 +366,7 @@ Document *sp_repr_read_file (const gchar * filename, const gchar *default_ns)
// 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);
- src.SystemCheck = true;
+ src.setFile(filename, true);
doc = src.readXml();
rdoc = sp_repr_do_read( doc, default_ns );
}