diff --git a/site/assets/files/1017/.phrase-index.txt b/site/assets/files/1017/.phrase-index.txt index 1f5fb50..6e94f66 100644 --- a/site/assets/files/1017/.phrase-index.txt +++ b/site/assets/files/1017/.phrase-index.txt @@ -1,7 +1,8 @@ |Content', 'Main content|^site--templates--_main-php:/site/templates/_main.php -|en', 'HTML language code|Skip to content', 'bypass|Menu', 'Navigation menu|^site--templates--_head-php:/site/templates/_head.php +|en', 'HTML language code|Skip to content', 'bypass|Logo of Praia de Seselle Tourist Apartments', 'Site logo|Open/Close menu', 'Menu Switch|Menu', 'Navigation menu|^site--templates--_head-php:/site/templates/_head.php |Footer', 'Page footer|All rights reserved', 'copyright|Designed and Developed by', 'developer|^site--templates--_foot-php:/site/templates/_foot.php |Info|SQL file|ZIP file|Backup|Delete|Restore|Cancel|Upload|Description|Valid?|Date/Time|Exported by|File size|Filename|Database name|Which tables?|Num tables exported|Num tables created|Num rows|Export time (seconds)|file', 'th|date', 'th|tables', 'th|rows', 'th|size', 'th|actions', 'th|(all)|No database backup files yet.|Delete checked|Add new SQL database dump file|Upload File|Added file: %s|Yes! Confirmed valid begin and end of file.|All Tables|Unable to confirm if valid file (likely not created by this tool)|bytes', 'file-details|Backup name|This will be used for the backup filename. The extension .sql will be added to it automatically.|If omitted, a unique filename will be automatically generated.|Backup description|Backup all tables?|Tables|By default, the export will include all tables. If you only want certain tables to be included, select them below.|Please be patient after clicking submit. Backups may take some time, depending on how much there is to backup.|Saved new backup:|Failed to create ZIP file: %s|Delete Backup|Delete %s?|Check the box to confirm|Restore Backup|Restored: %s|Error restoring: %s|Warning: the current database will be destroyed and replaced (this has potential to break your site!)|Restore %s?|Drop all tables from current database before restore?|Deleted: %s|^site--modules--processdatabasebackups--processdatabasebackups-module:/site/modules/ProcessDatabaseBackups/ProcessDatabaseBackups.module +|Remove remote references?|This will stop HTTP leaks but can increase the time it takes to sanitize.|Minify sanitized SVG files?|This will perform minification on whitespace in the sanitized SVG markup, potentially reducing the file size somewhat.|Add or remove tags (1 per line)|To add whitelisted tags, enter one per line. To remove tags, do the same but prefix line with a minus sign.|Add or remove attributes (1 per line)|To add whitelisted attributes, enter one per line. To remove attributes, do the same but prefix line with a minus sign.|^site--modules--filevalidatorsvgsanitizer-master--filevalidatorsvgsanitizer-config-php:/site/modules/FileValidatorSvgSanitizer-master/FileValidatorSvgSanitizer.config.php |Check for upgrades on superuser login?|If "No" is selected, then upgrades will only be checked manually when you click to Setup > Upgrades.|Automatic upgrade check requires ProcessWire 3.0.123 or newer.|Yes|No|^site--modules--processwireupgrade--processwireupgradecheck-config-php:/site/modules/ProcessWireUpgrade/ProcessWireUpgradeCheck.config.php |Remove|Continue|Module title|Module name|Installed|Latest|Status|Links|Up-to-date|Upgrade available|Not in directory|Refreshed module versions data|Removed: %s|Permission error removing path (please remove manually): %s|Download Now|Abort|Backup Database Now|Skip Database Backup|Confirm|Install|Core upgrade|Refresh|N/A|Last refresh: %s|^site--modules--processwireupgrade--processwireupgrade-module:/site/modules/ProcessWireUpgrade/ProcessWireUpgrade.module |A ProcessWire core upgrade is available|Your ProcessWire core is up-to-date|An upgrade for %s is available|Your modules are up-to-date|Error retrieving modules directory data|Error loading GitHub branches|HTTP error(s):|Check that HTTP requests are not blocked by your server.|^site--modules--processwireupgrade--processwireupgradecheck-module:/site/modules/ProcessWireUpgrade/ProcessWireUpgradeCheck.module diff --git a/site/assets/files/1017/site--templates--_head-php.json b/site/assets/files/1017/site--templates--_head-php.json index 1448484..92374ec 100644 --- a/site/assets/files/1017/site--templates--_head-php.json +++ b/site/assets/files/1017/site--templates--_head-php.json @@ -8,6 +8,12 @@ "01bea08b9a838113ed66226778ce6108": { "text": "Saltar al contenido" }, + "9a59fd41dc60086c1ba0b5ef77e05d4e": { + "text": "Logotipo de Praia de Seselle Apartamentos Tur\u00edsticos" + }, + "4da98e72b078f4590386d08a0a363404": { + "text": "Abrir\/Cerrar el men\u00fa" + }, "6772cbe29a38577eeabce0d6ca81817d": { "text": "Men\u00fa" } diff --git a/site/assets/files/1023/site--templates--_head-php.json b/site/assets/files/1023/site--templates--_head-php.json index d1bd992..97dd4dd 100644 --- a/site/assets/files/1023/site--templates--_head-php.json +++ b/site/assets/files/1023/site--templates--_head-php.json @@ -8,6 +8,12 @@ "01bea08b9a838113ed66226778ce6108": { "text": "Ir ao contido" }, + "9a59fd41dc60086c1ba0b5ef77e05d4e": { + "text": "Logotipo de Praia de Seselle Apartamentos Tur\u00edsticos" + }, + "4da98e72b078f4590386d08a0a363404": { + "text": "Abrir\/Pechar o men\u00fa" + }, "6772cbe29a38577eeabce0d6ca81817d": { "text": "Men\u00fa" } diff --git a/site/assets/files/1024/site--templates--_head-php.json b/site/assets/files/1024/site--templates--_head-php.json index 5ea36f2..d887596 100644 --- a/site/assets/files/1024/site--templates--_head-php.json +++ b/site/assets/files/1024/site--templates--_head-php.json @@ -8,6 +8,12 @@ "01bea08b9a838113ed66226778ce6108": { "text": "Skip to content" }, + "9a59fd41dc60086c1ba0b5ef77e05d4e": { + "text": "Logo of Praia de Seselle Tourist Apartments" + }, + "4da98e72b078f4590386d08a0a363404": { + "text": "Open\/Close menu" + }, "6772cbe29a38577eeabce0d6ca81817d": { "text": "Menu" } diff --git a/site/assets/files/1030/mantemento.0x260.jpg b/site/assets/files/1030/mantemento.0x260.jpg deleted file mode 100644 index 88b86fe..0000000 Binary files a/site/assets/files/1030/mantemento.0x260.jpg and /dev/null differ diff --git a/site/assets/files/1030/mantemento.jpg b/site/assets/files/1030/mantemento.jpg deleted file mode 100644 index 5b4163e..0000000 Binary files a/site/assets/files/1030/mantemento.jpg and /dev/null differ diff --git a/site/assets/files/1030/playa_chanteiro_ares.0x260.jpg b/site/assets/files/1030/playa_chanteiro_ares.0x260.jpg new file mode 100644 index 0000000..240eb2f Binary files /dev/null and b/site/assets/files/1030/playa_chanteiro_ares.0x260.jpg differ diff --git a/site/assets/files/1030/playa_chanteiro_ares.350x195.jpg b/site/assets/files/1030/playa_chanteiro_ares.350x195.jpg new file mode 100644 index 0000000..3740686 Binary files /dev/null and b/site/assets/files/1030/playa_chanteiro_ares.350x195.jpg differ diff --git a/site/assets/files/1030/playa_chanteiro_ares.jpg b/site/assets/files/1030/playa_chanteiro_ares.jpg new file mode 100644 index 0000000..8b7079e Binary files /dev/null and b/site/assets/files/1030/playa_chanteiro_ares.jpg differ diff --git a/site/modules/FileValidatorSvgSanitizer-master/FileValidatorSvgSanitizer.config.php b/site/modules/FileValidatorSvgSanitizer-master/FileValidatorSvgSanitizer.config.php new file mode 100644 index 0000000..c794e0b --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/FileValidatorSvgSanitizer.config.php @@ -0,0 +1,29 @@ + array( + 'type' => 'checkbox', + 'label' => __('Remove remote references?'), + 'description' => __('This will stop HTTP leaks but can increase the time it takes to sanitize.'), + 'value' => 1 + ), + 'minify' => array( + 'type' => 'checkbox', + 'label' => __('Minify sanitized SVG files?'), + 'description' => __('This will perform minification on whitespace in the sanitized SVG markup, potentially reducing the file size somewhat.'), + 'value' => 0 + ), + 'customTags' => array( + 'type' => 'textarea', + 'label' => __('Add or remove tags (1 per line)'), + 'description' => __('To add whitelisted tags, enter one per line. To remove tags, do the same but prefix line with a minus sign.'), + 'collapsed' => Inputfield::collapsedBlank + ), + 'customAttrs' => array( + 'type' => 'textarea', + 'label' => __('Add or remove attributes (1 per line)'), + 'description' => __('To add whitelisted attributes, enter one per line. To remove attributes, do the same but prefix line with a minus sign.'), + 'collapsed' => Inputfield::collapsedBlank + ) +); + diff --git a/site/modules/FileValidatorSvgSanitizer-master/FileValidatorSvgSanitizer.data.php b/site/modules/FileValidatorSvgSanitizer-master/FileValidatorSvgSanitizer.data.php new file mode 100644 index 0000000..8e8cd5d --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/FileValidatorSvgSanitizer.data.php @@ -0,0 +1,42 @@ + 'SVG File Sanitizer/Validator', + 'summary' => 'Validates and/or sanitizes uploaded SVG files.', + 'version' => 5, + 'author' => 'Adrian and Ryan', + 'autoload' => false, + 'singular' => false, + 'validates' => array('svg'), + 'requires' => 'ProcessWire>=3.0.148', + ); + } + + /** + * @var \enshrined\svgSanitize\Sanitizer + * + */ + protected $svgSanitizer = null; + + /** + * Construct + * + */ + public function __construct() { + $this->set('removeRemoteReferences', 1); + $this->set('minify', 0); + $this->set('customTags', ''); + $this->set('customAttrs', ''); + } + + /** + * Module init + * + */ + public function init() { + $this->getSvgSanitizer(); + } + + /** + * Get the SVG Sanitizer instance + * + * @return \enshrined\svgSanitize\Sanitizer + * + */ + public function getSvgSanitizer() { + if($this->svgSanitizer !== null) return $this->svgSanitizer; + $ns = 'enshrined\svgSanitize'; + $classLoader = $this->wire()->classLoader; + if(!$classLoader->hasNamespace($ns)) $classLoader->addNamespace($ns, __DIR__ . '/svgSanitize/'); + $className = $ns . '\Sanitizer'; + $this->svgSanitizer = new $className(); + $this->svgSanitizer->removeRemoteReferences((bool) $this->removeRemoteReferences); + $this->svgSanitizer->minify((bool) $this->minify); + list($tags, $attrs) = array($this->customTags, $this->customAttrs); + if($tags || $attrs) { + require_once(__DIR__ . '/FileValidatorSvgSanitizer.data.php'); + if($tags) { + FileValidatorSvgSanitizerTags::add($tags); + $this->svgSanitizer->setAllowedTags(new FileValidatorSvgSanitizerTags()); + } + if($attrs) { + FileValidatorSvgSanitizerAttributes::add($attrs); + $this->svgSanitizer->setAllowedAttrs(new FileValidatorSvgSanitizerAttributes()); + } + } + return $this->svgSanitizer; + } + + /** + * Is the given SVG file valid? + * + * This is for implementation of PW's FileValidator interface. + * + * This method should return: + * - boolean TRUE if file is valid + * - boolean FALSE if file is not valid + * - integer 1 if file is valid as a result of sanitization performed by this method + * + * If method wants to explain why the file is not valid, it should call $this->error('reason why not valid'). + * + * @param string $filename Full path and filename to the file + * @return bool|int + * + */ + protected function isValidFile($filename) { + + $svgSanitizer = $this->getSvgSanitizer(); + $svgDirty = file_get_contents($filename); + $svgClean = $svgSanitizer->sanitize($svgDirty); + $svgIssues = $svgSanitizer->getXmlIssues(); + + if(!empty($svgIssues)) { + // log found issues + $issues = array(); + foreach($svgIssues as $issue) { + $issue = "$issue[message] (line $issue[line])"; + $issues[$issue] = $issue; + } + if($svgClean === false) { + foreach($issues as $issue) $this->error($issue); + } else if(count($issues)) { + $this->log("SvgSanitizer: " . basename($filename) . ": " . implode(', ', $issues)); + } + } + + if($svgClean === false) { + // sanitize failed + return false; + + } else if($svgDirty === $svgClean) { + // no changes after sanitization, file is ok. this is sort of unlikely + // as SvgSanitizer seems to apply minor changes either way + return true; + } + + // write new sanitized svg file + $files = $this->wire()->files; + $files->unlink($filename); + if($files->filePutContents($filename, $svgClean) === false) return false; + + return 1; + } + + /** + * Return the data from the default whitelist + * + * This method doesn’t do anything for this module, it is just here if you want to + * know what are the whitelisted tags and attributes. + * + * @return array + * + */ + public function getDefaultWhitelist() { + return array( + 'tags' => \enshrined\svgSanitize\data\AllowedTags::getTags(), + 'attributes' => \enshrined\svgSanitize\data\AllowedAttributes::getAttributes(), + ); + } + + /** + * Return data from the customized whitelist + * + * @return array + * + */ + public function getWhitelist() { + $this->getSvgSanitizer(); + return array( + 'tags' => FileValidatorSvgSanitizerTags::getTags(), + 'attributes' => FileValidatorSvgSanitizerAttributes::getAttributes(), + ); + } + + /** + * Install + * + * @throws WireException + * + */ + public function ___install() { + $exts = get_loaded_extensions(); + if(!in_array('dom', $exts)) { + throw new WireException('This module requires the PHP “dom” extension (ext-dom)'); + } + if(!in_array('libxml', $exts)) { + throw new WireException('This module requires the PHP “libxml” extension (ext-libxml)'); + } + } + +} + diff --git a/site/modules/FileValidatorSvgSanitizer-master/README.md b/site/modules/FileValidatorSvgSanitizer-master/README.md new file mode 100644 index 0000000..f715037 --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/README.md @@ -0,0 +1,100 @@ +# ProcessWire SVG Sanitizer + +## A FileValidator module for ProcessWire 3.x + +Installation of this module is recommended if using SVG file uploads +in ProcessWire, as SVG files can easily contain malicious code. On the other hand, +if you do not need SVG file uploads then you should simply prevent their use by +never adding "svg" as a file extension to your file/image fields. + +When installed, this module will automatically sanitize SVG files uploaded to file +or image fields in ProcessWire (InputfieldFile and InputfieldImage). It will also +apply to anything else that calls the `$sanitizer->validateFile()` API method. + +This module does not guarantee that SVG files are safe, but it does help to +significantly reduce the risks associated with SVG files by sanitizing them from +known problematic tabs and attributes that can be present in SVG files. If you +want to be 100% safe then do not allow SVG file uploads at all. + +The FileValidatorModule interface and this module file are MIT licensed, +while the svg-sanitizer library in the /svgSanitize/ dir is GPL 2.0. +As a result, if your usage does not support GPL code, you should inquire with +the developer of the sanitizer lib before using this module in your project: + + +This module was developed by @adrianbj and @ryancramerdesign in 2015 and updated +in 2020 to replace the existing SVG library with a more up-to-date version located +at: + + +## Requirements + +- ProcessWire 3.0.148 or newer (3.0.164+ recommended). +- PHP must have the "dom" and "libxml" extensions (most already do). + + +## Install + +1. Copy all of the files for this module into a new directory named: + `/site/modules/FileValidatorSvgSanitizer/` +2. In your ProcessWire admin, navigate to: “Modules > Refresh” +3. Click “Install” for module “SVG File Sanitizer/Validator”. + + +## Upgrade + +To upgrade the module, remove your old FileValidatorSvgSanitizer directory +(or hide it by placing a period in front of it) and then follow steps 1 +and 2 of the Install directions above. + +Because of the SVG library change, please note the following feature changes +in version 2+ relative to version 1: + +1. It does not use a `$config->FileValidatorSvgSanitizer` config array. +2. Whitelists of tags and attributes are configurable in module settings. +3. It only rejects SVG files that cannot be made valid through sanitization. +4. Sanitization seems to be quite a bit better than the previous. +5. It optionally includes the ability to minify whitespace in an SVG file. +6. It performs more verbose logging of issues in the file-validator log. + + +## General usage + +This module is used automatically on any SVG files uploaded to file or image +fields in ProcessWire that use InputfieldFile or InputfieldImage. It is also +used on any SVG files passed to `$sanitizer->validateFile()`. + +Activity for this module can be found in “Setup > Logs > File-validator”. +It logs any issues it identifies and cleans out of SVG files. + +## API usage + +To use the module directly: +~~~~~ +$validator = $modules->get('FileValidatorSvgSanitizer'); +$result = $validator->isValid('/path/to/file.svg'); + +if($result === true) { + // true: file is valid as-is +} else if($result) { + // 1: file was made valid through sanitization +} else { + // false: file is not valid svg +} +~~~~~ +To use the module through the `$sanitizer` API var, you can validate +in the same way as any other file type: +~~~~~ +$result = $sanitizer->validateFile('/path/to/file.svg'); + +if($result === null) { + // null: no FileValidator module available for given file type +} else if($result) { + // true: file is valid or was made valid +} else { + // false: file is not valid +} +~~~~~ + + + diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Resolver.php b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Resolver.php new file mode 100644 index 0000000..cd7a840 --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Resolver.php @@ -0,0 +1,169 @@ +xPath = $xPath; + $this->useNestingLimit = $useNestingLimit; + } + + public function collect() + { + $this->collectIdentifiedElements(); + $this->processReferences(); + $this->determineInvalidSubjects(); + } + + /** + * Resolves one subject by element. + * + * @param \DOMElement $element + * @param bool $considerChildren Whether to search in Subject's children as well + * @return Subject|null + */ + public function findByElement(\DOMElement $element, $considerChildren = false) + { + foreach ($this->subjects as $subject) { + if ( + $element === $subject->getElement() + || $considerChildren && Helper::isElementContainedIn($element, $subject->getElement()) + ) { + return $subject; + } + } + return null; + } + + /** + * Resolves subjects (plural!) by element id - in theory malformed + * DOM might have same ids assigned to different elements and leaving + * it to client/browser implementation which element to actually use. + * + * @param string $elementId + * @return Subject[] + */ + public function findByElementId($elementId) + { + return array_filter( + $this->subjects, + function (Subject $subject) use ($elementId) { + return $elementId === $subject->getElementId(); + } + ); + } + + /** + * Collects elements having `id` attribute (those that can be referenced). + */ + protected function collectIdentifiedElements() + { + /** @var \DOMNodeList|\DOMElement[] $elements */ + $elements = $this->xPath->query('//*[@id]'); + foreach ($elements as $element) { + $this->subjects[$element->getAttribute('id')] = new Subject($element, $this->useNestingLimit); + } + } + + /** + * Processes references from and to elements having `id` attribute concerning + * their occurrence in `` statements. + */ + protected function processReferences() + { + $useNodeName = $this->xPath->createNodeName('use'); + foreach ($this->subjects as $subject) { + $useElements = $this->xPath->query( + $useNodeName . '[@href or @xlink:href]', + $subject->getElement() + ); + + /** @var \DOMElement $useElement */ + foreach ($useElements as $useElement) { + $useId = Helper::extractIdReferenceFromHref( + Helper::getElementHref($useElement) + ); + if ($useId === null || !isset($this->subjects[$useId])) { + continue; + } + $subject->addUse($this->subjects[$useId]); + $this->subjects[$useId]->addUsedIn($subject); + } + } + } + + /** + * Determines and tags infinite loops. + */ + protected function determineInvalidSubjects() + { + foreach ($this->subjects as $subject) { + + if (in_array($subject->getElement(), $this->elementsToRemove)) { + continue; + } + + $useId = Helper::extractIdReferenceFromHref( + Helper::getElementHref($subject->getElement()) + ); + + try { + if ($useId === $subject->getElementId()) { + $this->markSubjectAsInvalid($subject); + } elseif ($subject->hasInfiniteLoop()) { + $this->markSubjectAsInvalid($subject); + } + } catch (NestingException $e) { + $this->elementsToRemove[] = $e->getElement(); + $this->markSubjectAsInvalid($subject); + } + } + } + + /** + * Get all the elements that caused a nesting exception. + * + * @return array + */ + public function getElementsToRemove() { + return $this->elementsToRemove; + } + + /** + * The Subject is invalid for some reason, therefore we should + * remove it and all it's child usages. + * + * @param Subject $subject + */ + protected function markSubjectAsInvalid(Subject $subject) { + $this->elementsToRemove = array_merge( + $this->elementsToRemove, + $subject->clearInternalAndGetAffectedElements() + ); + } +} \ No newline at end of file diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Subject.php b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Subject.php new file mode 100644 index 0000000..3610f0f --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Subject.php @@ -0,0 +1,153 @@ +element = $element; + $this->useNestingLimit = $useNestingLimit; + } + + /** + * @return \DOMElement + */ + public function getElement() + { + return $this->element; + } + + /** + * @return string + */ + public function getElementId() + { + return $this->element->getAttribute('id'); + } + + /** + * @param array $subjects Previously processed subjects + * @param int $level The current level of nesting. + * @return bool + * @throws \enshrined\svgSanitize\Exceptions\NestingException + */ + public function hasInfiniteLoop(array $subjects = [], $level = 1) + { + if ($level > $this->useNestingLimit) { + throw new \enshrined\svgSanitize\Exceptions\NestingException('Nesting level too high, aborting', 1570713498, null, $this->getElement()); + } + + if (in_array($this, $subjects, true)) { + return true; + } + $subjects[] = $this; + foreach ($this->useCollection as $usage) { + if ($usage->getSubject()->hasInfiniteLoop($subjects, $level + 1)) { + return true; + } + } + return false; + } + + /** + * @param Subject $subject + */ + public function addUse(Subject $subject) + { + if ($subject === $this) { + throw new \LogicException('Cannot add self usage', 1570713416); + } + $identifier = $subject->getElementId(); + if (isset($this->useCollection[$identifier])) { + $this->useCollection[$identifier]->increment(); + return; + } + $this->useCollection[$identifier] = new Usage($subject); + } + + /** + * @param Subject $subject + */ + public function addUsedIn(Subject $subject) + { + if ($subject === $this) { + throw new \LogicException('Cannot add self as usage', 1570713417); + } + $identifier = $subject->getElementId(); + if (isset($this->usedInCollection[$identifier])) { + $this->usedInCollection[$identifier]->increment(); + return; + } + $this->usedInCollection[$identifier] = new Usage($subject); + } + + /** + * @param bool $accumulated + * @return int + */ + public function countUse($accumulated = false) + { + $count = 0; + foreach ($this->useCollection as $use) { + $useCount = $use->getSubject()->countUse(); + $count += $use->getCount() * ($accumulated ? 1 + $useCount : max(1, $useCount)); + } + return $count; + } + + /** + * @return int + */ + public function countUsedIn() + { + $count = 0; + foreach ($this->usedInCollection as $usedIn) { + $count += $usedIn->getCount() * max(1, $usedIn->getSubject()->countUsedIn()); + } + return $count; + } + + /** + * Clear the internal arrays (to free up memory as they can get big) + * and return all the child usages DOMElement's + * + * @return array + */ + public function clearInternalAndGetAffectedElements() + { + $elements = array_map(function(Usage $usage) { + return $usage->getSubject()->getElement(); + }, $this->useCollection); + + $this->usedInCollection = []; + $this->useCollection = []; + + return $elements; + } +} \ No newline at end of file diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Usage.php b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Usage.php new file mode 100644 index 0000000..d0ba62d --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/ElementReference/Usage.php @@ -0,0 +1,49 @@ +subject = $subject; + $this->count = (int)$count; + } + + /** + * @param int $by + */ + public function increment($by = 1) + { + $this->count += (int)$by; + } + + /** + * @return Subject + */ + public function getSubject() + { + return $this->subject; + } + + /** + * @return int + */ + public function getCount() + { + return $this->count; + } +} \ No newline at end of file diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Exceptions/NestingException.php b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Exceptions/NestingException.php new file mode 100644 index 0000000..cc7b4cb --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Exceptions/NestingException.php @@ -0,0 +1,39 @@ +element = $element; + parent::__construct($message, $code, $previous); + } + + /** + * Get the element that caused the exception. + * + * @return \DOMElement + */ + public function getElement() + { + return $this->element; + } +} \ No newline at end of file diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Helper.php b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Helper.php new file mode 100644 index 0000000..6e25003 --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Helper.php @@ -0,0 +1,53 @@ +hasAttribute('href')) { + return $element->getAttribute('href'); + } + if ($element->hasAttributeNS('http://www.w3.org/1999/xlink', 'href')) { + return $element->getAttributeNS('http://www.w3.org/1999/xlink', 'href'); + } + return null; + } + + /** + * @param string $href + * @return string|null + */ + public static function extractIdReferenceFromHref($href) + { + if (!is_string($href) || strpos($href, '#') !== 0) { + return null; + } + return substr($href, 1); + } + + /** + * @param \DOMElement $needle + * @param \DOMElement $haystack + * @return bool + */ + public static function isElementContainedIn(\DOMElement $needle, \DOMElement $haystack) + { + if ($needle === $haystack) { + return true; + } + foreach ($haystack->childNodes as $childNode) { + if (!$childNode instanceof \DOMElement) { + continue; + } + if (self::isElementContainedIn($needle, $childNode)) { + return true; + } + } + return false; + } +} diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/LICENSE b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/LICENSE new file mode 100644 index 0000000..8cdb845 --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/README.md b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/README.md new file mode 100644 index 0000000..c91a5cb --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/README.md @@ -0,0 +1,92 @@ +# svg-sanitizer + +[![Build Status](https://travis-ci.org/darylldoyle/svg-sanitizer.svg?branch=master)](https://travis-ci.org/darylldoyle/svg-sanitizer) [![Test Coverage](https://codeclimate.com/github/darylldoyle/svg-sanitizer/badges/coverage.svg)](https://codeclimate.com/github/darylldoyle/svg-sanitizer/coverage) + +This is my attempt at building a decent SVG sanitizer in PHP. The work is laregely borrowed from [DOMPurify](https://github.com/cure53/DOMPurify). + +## Installation + +Either require `enshrined/svg-sanitize` through composer or download the repo and include the old way! + +## Usage + +Using this is fairly easy. Create a new instance of `enshrined\svgSanitize\Sanitizer` and then call the `sanitize` whilst passing in your dirty SVG/XML + +**Basic Example** + +```php +use enshrined\svgSanitize\Sanitizer; + +// Create a new sanitizer instance +$sanitizer = new Sanitizer(); + +// Load the dirty svg +$dirtySVG = file_get_contents('filthy.svg'); + +// Pass it to the sanitizer and get it back clean +$cleanSVG = $sanitizer->sanitize($dirtySVG); + +// Now do what you want with your clean SVG/XML data + +``` + +## Output + +This will either return a sanitized SVG/XML string or boolean `false` if XML parsing failed (usually due to a badly formatted file). + +## Options + +You may pass your own whitelist of tags and attributes by using the `Sanitizer::setAllowedTags` and `Sanitizer::setAllowedAttrs` methods respectively. + +These methods require that you implement the `enshrined\svgSanitize\data\TagInterface` or `enshrined\svgSanitize\data\AttributeInterface`. + +## Remove remote references + +You have the option to remove attributes that reference remote files, this will stop HTTP leaks but will add an overhead to the sanitizer. + +This defaults to false, set to true to remove references. + +`$sanitizer->removeRemoteReferences(true);` + +## Viewing Sanitization Issues + +You may use the `getXmlIssues()` method to return an array of issues that occurred during sanitization. + +This may be useful for logging or providing feedback to the user on why an SVG was refused. + +`$issues = $sanitizer->getXmlIssues();` + +## Minification + +You can minify the XML output by calling `$sanitizer->minify(true);`. + +## Demo +There is a demo available at: [http://svg.enshrined.co.uk/](http://svg.enshrined.co.uk/) + +## WordPress + +I've just released a WordPress plugin containing this code so you can sanitize your WordPress uploads. It's available from the WordPress plugin directory: [https://wordpress.org/plugins/safe-svg/](https://wordpress.org/plugins/safe-svg/) + +## Drupal + +[Michael Potter](https://github.com/heyMP) has kindly created a Drupal module for this library which is available at: [https://www.drupal.org/project/svg_sanitizer](https://www.drupal.org/project/svg_sanitizer) + +## TYPO3 + +An integration for TYPO3 CMS of this library is available as composer package `t3g/svg-sanitizer` at [https://github.com/TYPO3GmbH/svg_sanitizer](https://github.com/TYPO3GmbH/svg_sanitizer) + +## Tests + +You can run these by running `vendor/bin/phpunit` from the base directory of this package. + +## Standalone scanning of files via CLI + +Thanks to the work by [gudmdharalds](https://github.com/gudmdharalds) there's now a standalone scanner that can be used via the CLI. + +Any errors will be output in JSON format. See [the PR](https://github.com/darylldoyle/svg-sanitizer/pull/25) for an example. + +Use it as follows: `php svg-scanner.php ~/svgs/myfile.svg` + +## To-Do + +More extensive testing for the SVGs/XML would be lovely, I'll try and add these soon. If you feel like doing it for me, please do and make a PR! diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Sanitizer.php b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Sanitizer.php new file mode 100644 index 0000000..58c8111 --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/Sanitizer.php @@ -0,0 +1,630 @@ +allowedAttrs = array_map('strtolower', AllowedAttributes::getAttributes()); + $this->allowedTags = array_map('strtolower', AllowedTags::getTags()); + } + + /** + * Set up the DOMDocument + */ + protected function resetInternal() + { + $this->xmlDocument = new \DOMDocument(); + $this->xmlDocument->preserveWhiteSpace = false; + $this->xmlDocument->strictErrorChecking = false; + $this->xmlDocument->formatOutput = !$this->minifyXML; + } + + /** + * Set XML options to use when saving XML + * See: DOMDocument::saveXML + * + * @param int $xmlOptions + */ + public function setXMLOptions($xmlOptions) + { + $this->xmlOptions = $xmlOptions; + } + + /** + * Get XML options to use when saving XML + * See: DOMDocument::saveXML + * + * @return int + */ + public function getXMLOptions() + { + return $this->xmlOptions; + } + + /** + * Get the array of allowed tags + * + * @return array + */ + public function getAllowedTags() + { + return $this->allowedTags; + } + + /** + * Set custom allowed tags + * + * @param TagInterface $allowedTags + */ + public function setAllowedTags(TagInterface $allowedTags) + { + $this->allowedTags = array_map('strtolower', $allowedTags::getTags()); + } + + /** + * Get the array of allowed attributes + * + * @return array + */ + public function getAllowedAttrs() + { + return $this->allowedAttrs; + } + + /** + * Set custom allowed attributes + * + * @param AttributeInterface $allowedAttrs + */ + public function setAllowedAttrs(AttributeInterface $allowedAttrs) + { + $this->allowedAttrs = array_map('strtolower', $allowedAttrs::getAttributes()); + } + + /** + * Should we remove references to remote files? + * + * @param bool $removeRemoteRefs + */ + public function removeRemoteReferences($removeRemoteRefs = false) + { + $this->removeRemoteReferences = $removeRemoteRefs; + } + + /** + * Get XML issues. + * + * @return array + */ + public function getXmlIssues() { + return $this->xmlIssues; + } + + + /** + * Sanitize the passed string + * + * @param string $dirty + * @return string + */ + public function sanitize($dirty) + { + // Don't run on an empty string + if (empty($dirty)) { + return ''; + } + + // Strip php tags + $dirty = preg_replace('/<\?(=|php)(.+?)\?>/i', '', $dirty); + + $this->resetInternal(); + $this->setUpBefore(); + + $loaded = $this->xmlDocument->loadXML($dirty); + + // If we couldn't parse the XML then we go no further. Reset and return false + if (!$loaded) { + $this->resetAfter(); + return false; + } + + // Pre-process all identified elements + $xPath = new XPath($this->xmlDocument); + $this->elementReferenceResolver = new Resolver($xPath, $this->useNestingLimit); + $this->elementReferenceResolver->collect(); + $elementsToRemove = $this->elementReferenceResolver->getElementsToRemove(); + + // Grab all the elements + $allElements = $this->xmlDocument->getElementsByTagName("*"); + + // remove doctype after node elements have been analyzed + $this->removeDoctype(); + // Start the cleaning proccess + $this->startClean($allElements, $elementsToRemove); + + // Save cleaned XML to a variable + if ($this->removeXMLTag) { + $clean = $this->xmlDocument->saveXML($this->xmlDocument->documentElement, $this->xmlOptions); + } else { + $clean = $this->xmlDocument->saveXML($this->xmlDocument, $this->xmlOptions); + } + + $this->resetAfter(); + + // Remove any extra whitespaces when minifying + if ($this->minifyXML) { + $clean = preg_replace('/\s+/', ' ', $clean); + } + + // Return result + return $clean; + } + + /** + * Set up libXML before we start + */ + protected function setUpBefore() + { + // This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading is + // disabled by default, so this function is no longer needed to protect against XXE attacks. + if (\LIBXML_VERSION < 20900) { + // Turn off the entity loader + $this->xmlLoaderValue = libxml_disable_entity_loader(true); + } + + // Suppress the errors because we don't really have to worry about formation before cleansing + libxml_use_internal_errors(true); + + // Reset array of altered XML + $this->xmlIssues = array(); + } + + /** + * Reset the class after use + */ + protected function resetAfter() + { + // This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading is + // disabled by default, so this function is no longer needed to protect against XXE attacks. + if (\LIBXML_VERSION < 20900) { + // Reset the entity loader + libxml_disable_entity_loader($this->xmlLoaderValue); + } + } + + /** + * Remove the XML Doctype + * It may be caught later on output but that seems to be buggy, so we need to make sure it's gone + */ + protected function removeDoctype() + { + foreach ($this->xmlDocument->childNodes as $child) { + if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { + $child->parentNode->removeChild($child); + } + } + } + + /** + * Start the cleaning with tags, then we move onto attributes and hrefs later + * + * @param \DOMNodeList $elements + * @param array $elementsToRemove + */ + protected function startClean(\DOMNodeList $elements, array $elementsToRemove) + { + // loop through all elements + // we do this backwards so we don't skip anything if we delete a node + // see comments at: http://php.net/manual/en/class.domnamednodemap.php + for ($i = $elements->length - 1; $i >= 0; $i--) { + /** @var \DOMElement $currentElement */ + $currentElement = $elements->item($i); + + /** + * If the element has exceeded the nesting limit, we should remove it. + * + * As it's only elements that cause us issues with nesting DOS attacks + * we should check what the element is before removing it. For now we'll only + * remove elements. + */ + if (in_array($currentElement, $elementsToRemove) && 'use' === $currentElement->nodeName) { + $currentElement->parentNode->removeChild($currentElement); + $this->xmlIssues[] = array( + 'message' => 'Invalid \'' . $currentElement->tagName . '\'', + 'line' => $currentElement->getLineNo(), + ); + continue; + } + + // If the tag isn't in the whitelist, remove it and continue with next iteration + if (!in_array(strtolower($currentElement->tagName), $this->allowedTags)) { + $currentElement->parentNode->removeChild($currentElement); + $this->xmlIssues[] = array( + 'message' => 'Suspicious tag \'' . $currentElement->tagName . '\'', + 'line' => $currentElement->getLineNo(), + ); + continue; + } + + $this->cleanHrefs($currentElement); + + $this->cleanXlinkHrefs($currentElement); + + $this->cleanAttributesOnWhitelist($currentElement); + + if (strtolower($currentElement->tagName) === 'use') { + if ($this->isUseTagDirty($currentElement) + || $this->isUseTagExceedingThreshold($currentElement) + ) { + $currentElement->parentNode->removeChild($currentElement); + $this->xmlIssues[] = array( + 'message' => 'Suspicious \'' . $currentElement->tagName . '\'', + 'line' => $currentElement->getLineNo(), + ); + continue; + } + } + } + } + + /** + * Only allow attributes that are on the whitelist + * + * @param \DOMElement $element + */ + protected function cleanAttributesOnWhitelist(\DOMElement $element) + { + for ($x = $element->attributes->length - 1; $x >= 0; $x--) { + // get attribute name + $attrName = $element->attributes->item($x)->name; + + // Remove attribute if not in whitelist + if (!in_array(strtolower($attrName), $this->allowedAttrs) && !$this->isAriaAttribute(strtolower($attrName)) && !$this->isDataAttribute(strtolower($attrName))) { + + $element->removeAttribute($attrName); + $this->xmlIssues[] = array( + 'message' => 'Suspicious attribute \'' . $attrName . '\'', + 'line' => $element->getLineNo(), + ); + } + + /** + * This is used for when a namespace isn't imported properly. + * Such as xlink:href when the xlink namespace isn't imported. + * We have to do this as the link is still ran in this case. + */ + if (false !== strpos($attrName, 'href')) { + $href = $element->getAttribute($attrName); + if (false === $this->isHrefSafeValue($href)) { + $element->removeAttribute($attrName); + $this->xmlIssues[] = array( + 'message' => 'Suspicious attribute \'href\'', + 'line' => $element->getLineNo(), + ); + } + } + + // Do we want to strip remote references? + if($this->removeRemoteReferences) { + // Remove attribute if it has a remote reference + if (isset($element->attributes->item($x)->value) && $this->hasRemoteReference($element->attributes->item($x)->value)) { + $element->removeAttribute($attrName); + $this->xmlIssues[] = array( + 'message' => 'Suspicious attribute \'' . $attrName . '\'', + 'line' => $element->getLineNo(), + ); + } + } + } + } + + /** + * Clean the xlink:hrefs of script and data embeds + * + * @param \DOMElement $element + */ + protected function cleanXlinkHrefs(\DOMElement $element) + { + $xlinks = $element->getAttributeNS('http://www.w3.org/1999/xlink', 'href'); + if (false === $this->isHrefSafeValue($xlinks)) { + $element->removeAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ); + $this->xmlIssues[] = array( + 'message' => 'Suspicious attribute \'href\'', + 'line' => $element->getLineNo(), + ); + } + } + + /** + * Clean the hrefs of script and data embeds + * + * @param \DOMElement $element + */ + protected function cleanHrefs(\DOMElement $element) + { + $href = $element->getAttribute('href'); + if (false === $this->isHrefSafeValue($href)) { + $element->removeAttribute('href'); + $this->xmlIssues[] = array( + 'message' => 'Suspicious attribute \'href\'', + 'line' => $element->getLineNo(), + ); + } + } + +/** + * Only allow whitelisted starts to be within the href. + * + * This will stop scripts etc from being passed through, with or without attempting to hide bypasses. + * This stops the need for us to use a complicated script regex. + * + * @param $value + * @return bool + */ + protected function isHrefSafeValue($value) { + + // Allow empty values + if (empty($value)) { + return true; + } + + // Allow fragment identifiers. + if ('#' === substr($value, 0, 1)) { + return true; + } + + // Allow relative URIs. + if ('/' === substr($value, 0, 1)) { + return true; + } + + // Allow HTTPS domains. + if ('https://' === substr($value, 0, 8)) { + return true; + } + + // Allow HTTP domains. + if ('http://' === substr($value, 0, 7)) { + return true; + } + + // Allow known data URIs. + if (in_array(substr($value, 0, 14), array( + 'data:image/png', // PNG + 'data:image/gif', // GIF + 'data:image/jpg', // JPG + 'data:image/jpe', // JPEG + 'data:image/pjp', // PJPEG + ))) { + return true; + } + + // Allow known short data URIs. + if (in_array(substr($value, 0, 12), array( + 'data:img/png', // PNG + 'data:img/gif', // GIF + 'data:img/jpg', // JPG + 'data:img/jpe', // JPEG + 'data:img/pjp', // PJPEG + ))) { + return true; + } + + return false; + } + + /** + * Removes non-printable ASCII characters from string & trims it + * + * @param string $value + * @return bool + */ + protected function removeNonPrintableCharacters($value) + { + return trim(preg_replace('/[^ -~]/xu','',$value)); + } + + /** + * Does this attribute value have a remote reference? + * + * @param $value + * @return bool + */ + protected function hasRemoteReference($value) + { + $value = $this->removeNonPrintableCharacters($value); + + $wrapped_in_url = preg_match('~^url\(\s*[\'"]\s*(.*)\s*[\'"]\s*\)$~xi', $value, $match); + if (!$wrapped_in_url){ + return false; + } + + $value = trim($match[1], '\'"'); + + return preg_match('~^((https?|ftp|file):)?//~xi', $value); + } + + /** + * Should we minify the output? + * + * @param bool $shouldMinify + */ + public function minify($shouldMinify = false) + { + $this->minifyXML = (bool) $shouldMinify; + } + + /** + * Should we remove the XML tag in the header? + * + * @param bool $removeXMLTag + */ + public function removeXMLTag($removeXMLTag = false) + { + $this->removeXMLTag = (bool) $removeXMLTag; + } + + /** + * Whether `` elements shall be + * removed in case expansion would exceed this threshold. + * + * @param int $useThreshold + */ + public function useThreshold($useThreshold = 1000) + { + $this->useThreshold = (int)$useThreshold; + } + + /** + * Check to see if an attribute is an aria attribute or not + * + * @param $attributeName + * + * @return bool + */ + protected function isAriaAttribute($attributeName) + { + return strpos($attributeName, 'aria-') === 0; + } + + /** + * Check to see if an attribute is an data attribute or not + * + * @param $attributeName + * + * @return bool + */ + protected function isDataAttribute($attributeName) + { + return strpos($attributeName, 'data-') === 0; + } + + /** + * Make sure our use tag is only referencing internal resources + * + * @param \DOMElement $element + * @return bool + */ + protected function isUseTagDirty(\DOMElement $element) + { + $href = Helper::getElementHref($element); + return $href && strpos($href, '#') !== 0; + } + + /** + * Determines whether `` is expanded + * recursively in order to create DoS scenarios. The amount of a actually + * used element needs to be below `$this->useThreshold`. + * + * @param \DOMElement $element + * @return bool + */ + protected function isUseTagExceedingThreshold(\DOMElement $element) + { + if ($this->useThreshold <= 0) { + return false; + } + $useId = Helper::extractIdReferenceFromHref( + Helper::getElementHref($element) + ); + if ($useId === null) { + return false; + } + foreach ($this->elementReferenceResolver->findByElementId($useId) as $subject) { + if ($subject->countUse() >= $this->useThreshold) { + return true; + } + } + return false; + } + + /** + * Set the nesting limit for tags. + * + * @param $limit + */ + public function setUseNestingLimit($limit) + { + $this->useNestingLimit = (int) $limit; + } +} diff --git a/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/data/AllowedAttributes.php b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/data/AllowedAttributes.php new file mode 100644 index 0000000..a192934 --- /dev/null +++ b/site/modules/FileValidatorSvgSanitizer-master/svgSanitize/data/AllowedAttributes.php @@ -0,0 +1,357 @@ +handleDefaultNamespace(); + } + + /** + * @param string $nodeName + * @return string + */ + public function createNodeName($nodeName) + { + if (empty($this->defaultNamespaceURI)) { + return $nodeName; + } + return self::DEFAULT_NAMESPACE_PREFIX . ':' . $nodeName; + } + + protected function handleDefaultNamespace() + { + $rootElements = $this->getRootElements(); + + if (count($rootElements) !== 1) { + throw new \LogicException( + sprintf('Got %d svg elements, expected exactly one', count($rootElements)), + 1570870568 + ); + } + $this->defaultNamespaceURI = (string)$rootElements[0]->namespaceURI; + + if ($this->defaultNamespaceURI !== '') { + $this->registerNamespace(self::DEFAULT_NAMESPACE_PREFIX, $this->defaultNamespaceURI); + } + } + + /** + * @return \DOMElement[] + */ + protected function getRootElements() + { + $rootElements = []; + $elements = $this->document->getElementsByTagName('svg'); + /** @var \DOMElement $element */ + foreach ($elements as $element) { + if ($element->parentNode !== $this->document) { + continue; + } + $rootElements[] = $element; + } + return $rootElements; + } +} diff --git a/site/templates/_head.php b/site/templates/_head.php index 98076d2..1db793d 100644 --- a/site/templates/_head.php +++ b/site/templates/_head.php @@ -20,10 +20,9 @@ - viewable($idioma)): continue; endif; ?> - + @@ -31,8 +30,12 @@
diff --git a/site/templates/css/style.css b/site/templates/css/style.css index baa0705..5024ff0 100644 --- a/site/templates/css/style.css +++ b/site/templates/css/style.css @@ -73,6 +73,18 @@ img width: 100%; } +picture +{ + align-items: center; + display: flex; + justify-content: center; +} + +picture img +{ + width: 150px; +} + header#cabeceira { margin-bottom: 1.125rem; @@ -84,8 +96,6 @@ div#logo { width: 230px !important; height: 169px; - - background-image: url(../images/logo.jpg); } header#cabeceira input#interruptor @@ -396,6 +406,14 @@ footer#pe a color: rgb(var(--color_60)); } +@media (min-width:768px) +{ + picture img + { + width: 230px; + } +} + @media (max-height: 768px) and (orientation: landscape) { ul#idiomas diff --git a/site/templates/images/logo-praia-seselle-150x116.jpg b/site/templates/images/logo-praia-seselle-150x116.jpg new file mode 100644 index 0000000..0521dc2 Binary files /dev/null and b/site/templates/images/logo-praia-seselle-150x116.jpg differ diff --git a/site/templates/images/logo-praia-seselle-230x179.jpg b/site/templates/images/logo-praia-seselle-230x179.jpg new file mode 100644 index 0000000..77fae9d Binary files /dev/null and b/site/templates/images/logo-praia-seselle-230x179.jpg differ diff --git a/site/templates/images/logo-praia-seselle.svg b/site/templates/images/logo-praia-seselle.svg new file mode 100644 index 0000000..28ce1b2 --- /dev/null +++ b/site/templates/images/logo-praia-seselle.svg @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +