Я создаю диаграммы «на лету» как SVG, используя d3.js. Эти диаграммы динамически генерируются на основе выбранных пользователей. После создания этих диаграмм пользователь может загрузить сгенерированный SVG в виде PNG или PDF.
Текущий рабочий процесс следующий:
// JAVASC // get the element containing generated SVG var svg = document.getElementById("chart-container"); // Extract the data as SVG text string var svg_xml = (new XMLSerializer).serializeToString(svg); // Submit the <FORM> to the server. var form = document.getElementById("svgform"); form['output_format'].value = output_format; // can be either "pdf" or "png" form['data'].value = svg_xml ; form.submit();
Элемент FORM является скрытой формой, используемой для POST-данных:
<form id="svgform" method="post" action="conversion.php"> <input type="hidden" id="output_format" name="output_format" value=""> <input type="hidden" id="data" name="data" value=""> </form>
Файл PHP сохраняет предоставленные данные SVG в качестве временного файла:
// check for valid session, etc - omitted for brevity $xmldat = $_POST['data']; // serialized XML representing the SVG element if(simplexml_load_string($xmldat)===FALSE) { die; } // reject invalid XML $fileformat = $_POST['output_format']; // chosen format for output; PNG or PDF if ($fileformat != "pdf" && $fileformat != "png" ){ die; } // limited options for format $fileformat = escapeshellarg($fileformat); // escape shell arguments that might have snuck in // generate temporary file names with tempnam() - omitted for brevity $handle = fopen($infile, "w"); fwrite($handle, $xmldat); fclose($handle);
Запускается утилита преобразования, которая считывает временный файл ($ infile) и создает новый файл ($ outfile) в указанном файле $ fileformat (PDF или PNG). Полученный новый файл затем возвращается в браузер, а временные файлы удаляются:
// headers etc generated - omitted for brevity readfile($outfile); unlink($infile); // delete temporary infile unlink($outfile); // delete temporary outfile
Я исследовал преобразование SVG в PNG с использованием JavaScript (canvg (), затем toDataURL, затем document.write) и может использовать это для генерации PNG, но это не позволяет конвертировать в PDF.
Итак: как я могу наилучшим образом дезинфицировать или фильтровать данные SVG, которые предоставляются для convert.php, прежде чем он будет записан в файл? Каково нынешнее состояние санитарии SVG? Что доступно в PHP? Должен ли я идти с использованием подхода, основанного на белом списке, для дезинфекции данных SVG, предоставляемых convert.php, или есть лучший способ?
(Я не знаю XSLT, хотя я мог бы попытаться изучить его, я надеюсь как можно больше сохранить санитацию в PHP. Использование Windows Server 2008, поэтому любые решения, которые используют внешние инструменты, должны быть доступны в этой экосистеме.)
Я работаю с xml и PHP, но я не совсем уверен в вашем вопросе. Пожалуйста, принимайте это как идею / предложение, а не больше.
SimpleXML использует libxml для загрузки содержимого xml. http://www.php.net/manual/en/simplexml.requirements.php
Вы можете отключить внешние объекты, используя:
libxml_disable_entity_loader (TRUE)
http://www.php.net/manual/en/function.libxml-disable-entity-loader.php
перед загрузкой файла с помощью simpleXML.
Затем вы можете проверить правильность схемы SVG
http://us3.php.net/manual/en/domdocument.schemavalidate.php или http://us3.php.net/manual/en/domdocument.validate.php
Единственное, что я вижу, это то, что svg может содержать элемент сценария. http://www.w3.org/TR/SVG/script.html#ScriptElement
Здесь представлена информация об 1.1 DTD: http://www.w3.org/Graphics/SVG/1.1/DTD/svg-framework.mod http://www.w3.org/TR/2003/REC-SVG11-20030114/ REC-SVG11-20030114.pdf
Вы могли бы предоставить SVG DTD с модифицированной версией элемента сценария или циклическими элементами, чтобы предотвратить присутствие элемента сценария.
Это будет не идеально, но, по крайней мере, лучше, чем ничего.