summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEduard Braun <eduard.braun2@gmx.de>2017-02-10 21:26:04 +0000
committerEduard Braun <eduard.braun2@gmx.de>2017-02-10 21:26:04 +0000
commitbd4bad24c8e2c428e07d8afc5bc1009e9809be1b (patch)
treed191d134fbd5dcead8b3ec5aac643aa581568a03 /src
parentDo not delete presentation attributes. Styling source is now tracked (diff)
downloadinkscape-bd4bad24c8e2c428e07d8afc5bc1009e9809be1b.tar.gz
inkscape-bd4bad24c8e2c428e07d8afc5bc1009e9809be1b.zip
Fix encoding/escaping issues with symbols loaded from .vss (Visio stencils) files
There were three issues: - When loading a .vss file an SVG document is created internally and the file name is used to derive this document's "title". This could result in illegal characters (e.g. the ampersand "&") in the title making the document fail to load. The title is now properly escaped. - Loading of files with non-ANSI characers in filename failed on Windows. Fix is equivalent to r15421, see also bug #1416949. - The .vss file name is also used to derive symbol IDs, which were not properly sanitized before (i.e. could cause broken hrefs later or even prevent to load the .vss file). Characters that do not match [a-zA-Z0-9_-] are now laways replaced with an underscore "_") which will result in valid IDs in almost all cases Fixed bugs: - https://launchpad.net/bugs/1662465 (bzr r15501)
Diffstat (limited to 'src')
-rw-r--r--src/ui/dialog/symbols.cpp47
1 files changed, 28 insertions, 19 deletions
diff --git a/src/ui/dialog/symbols.cpp b/src/ui/dialog/symbols.cpp
index 4840b897b..c8a11b112 100644
--- a/src/ui/dialog/symbols.cpp
+++ b/src/ui/dialog/symbols.cpp
@@ -127,7 +127,7 @@ SymbolsDialog::SymbolsDialog( gchar const* prefsPath ) :
sigc::connection connSet = symbolSet->signal_changed().connect(
sigc::mem_fun(*this, &SymbolsDialog::rebuild));
instanceConns.push_back(connSet);
-
+
++row;
/********************* Icon View **************************/
@@ -342,7 +342,7 @@ void SymbolsDialog::rebuild() {
addSymbol->set_sensitive( true );
removeSymbol->set_sensitive( true );
} else {
- addSymbol->set_sensitive( false );
+ addSymbol->set_sensitive( false );
removeSymbol->set_sensitive( false );
}
add_symbols( symbolDocument );
@@ -451,7 +451,14 @@ void SymbolsDialog::iconChanged() {
#ifdef WITH_LIBVISIO
// Read Visio stencil files
-SPDocument* read_vss( gchar* fullname, gchar* filename ) {
+SPDocument* read_vss( gchar* fullname, Glib::ustring name ) {
+
+ #ifdef WIN32
+ // RVNGFileStream uses fopen() internally which unfortunately only uses ANSI encoding on Windows
+ // therefore attempt to convert uri to the system codepage
+ // even if this is not possible the alternate short (8.3) file name will be used if available
+ fullname = g_win32_locale_filename_from_utf8(fullname);
+ #endif
RVNGFileStream input(fullname);
@@ -474,6 +481,12 @@ SPDocument* read_vss( gchar* fullname, gchar* filename ) {
return NULL;
}
+ // prepare a valid title for the symbol file
+ Glib::ustring title = Glib::Markup::escape_text(name);
+ // prepare a valid id prefix for the symbols (unfortunately libvisio doesn't give us a name)
+ Glib::RefPtr<Glib::Regex> regex1 = Glib::Regex::create("[^a-zA-Z0-9_-]");
+ Glib::ustring id = regex1->replace(name, 0, "_", Glib::REGEX_MATCH_PARTIAL);
+
Glib::ustring tmpSVGOutput;
tmpSVGOutput += "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n";
tmpSVGOutput += "<svg\n";
@@ -483,17 +496,10 @@ SPDocument* read_vss( gchar* fullname, gchar* filename ) {
tmpSVGOutput += " version=\"1.1\"\n";
tmpSVGOutput += " style=\"fill:none;stroke:#000000;stroke-width:2\">\n";
tmpSVGOutput += " <title>";
- tmpSVGOutput += filename;
+ tmpSVGOutput += title;
tmpSVGOutput += "</title>\n";
tmpSVGOutput += " <defs>\n";
- // Create a string we can use for the symbol id (libvisio doesn't give us a name)
- std::string sanitized( filename );
- sanitized.erase( sanitized.find_last_of(".vss")-3 );
- sanitized.erase( std::remove_if( sanitized.begin(), sanitized.end(), ispunct ), sanitized.end() );
- std::replace( sanitized.begin(), sanitized.end(), ' ', '_' );
- // std::cout << filename << " |" << sanitized << "|" << std::endl;
-
// Each "symbol" is in it's own SVG file, we wrap with <symbol> and merge into one file.
for (unsigned i=0; i<output.size(); ++i) {
@@ -501,7 +507,7 @@ SPDocument* read_vss( gchar* fullname, gchar* filename ) {
ss << i;
tmpSVGOutput += " <symbol id=\"";
- tmpSVGOutput += sanitized;
+ tmpSVGOutput += id;
tmpSVGOutput += "_";
tmpSVGOutput += ss.str();
tmpSVGOutput += "\">\n";
@@ -521,12 +527,12 @@ SPDocument* read_vss( gchar* fullname, gchar* filename ) {
tmpSVGOutput += " </defs>\n";
tmpSVGOutput += "</svg>\n";
-
+
return SPDocument::createNewDocFromMem( tmpSVGOutput.c_str(), strlen( tmpSVGOutput.c_str()), 0 );
}
#endif
-
+
/* Hunts preference directories for symbol files */
void SymbolsDialog::get_symbols() {
@@ -565,11 +571,14 @@ void SymbolsDialog::get_symbols() {
#ifdef WITH_LIBVISIO
if( tag.compare( "vss" ) == 0 ) {
+ // strip extension from filename and use it as name for the symbol set
+ Glib::ustring name = Glib::ustring(filename);
+ name = name.erase(name.rfind('.'));
- symbol_doc = read_vss( fullname, filename );
+ symbol_doc = read_vss( fullname, name );
if( symbol_doc ) {
- symbolSets[Glib::ustring(filename)]= symbol_doc;
- symbolSet->append(filename);
+ symbolSets[name]= symbol_doc;
+ symbolSet->append(name);
}
}
#endif
@@ -630,7 +639,7 @@ GSList* SymbolsDialog::symbols_in_doc( SPDocument* symbolDocument ) {
}
GSList* SymbolsDialog::use_in_doc_recursive (SPObject *r, GSList *l)
-{
+{
if ( dynamic_cast<SPUse *>(r) ) {
l = g_slist_prepend (l, r);
@@ -816,7 +825,7 @@ SPDocument* SymbolsDialog::symbols_preview_doc()
" xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\""
" xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\""
" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
-" <defs id=\"defs\">"
+" <defs id=\"defs\">"
" <symbol id=\"the_symbol\"/>"
" </defs>"
" <use id=\"the_use\" xlink:href=\"#the_symbol\"/>"