1
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2025-08-03 12:47:56 +02:00

Compare commits

...

210 Commits

Author SHA1 Message Date
Gabriel R. Barbosa
1eb05d9864 feat: Support PHP 8.5 versions (#453) 2025-07-21 22:38:54 -04:00
Pieter Oliver
9f99c615bd add the docker files to be ignored with installation (#451) 2025-07-21 13:53:59 -04:00
Kieran
418eeb7dc0 fix: catastrophic backtracking in Core.AggressivelyFixLt (#440) 2025-06-05 23:49:52 -04:00
Tim Otten
77ebd08632 feat: Define option URI.AllowedSymbols (#447) 2025-06-05 22:46:45 -04:00
Saeid Dadkhah
127ee2f252 Update Serializer.php (#443) 2025-06-05 22:43:51 -04:00
Eli Barbosa
bdabc9b6ba Add docker files for dev environment (#424) 2025-06-05 22:42:52 -04:00
Kieran
ff005f6edc feat: PHP 8.4 support (#441) 2025-03-19 13:25:28 -04:00
Pieter Oliver
c2bc3549a3 fix: non-substantive typos (#434)
Co-authored-by: Viktor Szépe <viktor@szepe.net>
Co-authored-by: Edward Z. Yang <ezyang@mit.edu>
2025-01-14 16:31:27 -05:00
simonLeary42
b21a59101f fix: add warning for misleading option (#433) 2025-01-09 23:09:09 -05:00
Tim Otten
00a0748427 feat: Allow more image widths by default (#430) 2024-12-11 14:15:46 -05:00
Morgan Klonteig
63e631ebd3 feat: Add CSS direction support (#429) 2024-11-21 23:46:53 -05:00
nikkii94
5d154a2393 fix: Deprecated: preg_replace(): Passing null to parameter #3 ($subject) o… (#421)
Co-authored-by: Edward Z. Yang <ezyang@meta.com>
2024-11-09 22:06:41 -05:00
rio
d5150073e9 refactor: #414 remove method substrCount (#415)
Co-authored-by: Edward Z. Yang <ezyang@meta.com>
2024-11-09 22:06:09 -05:00
Eli Barbosa
b5cbf0cc3d feat: Add option for safe iframe hosts using array lookup (#423)
Co-authored-by: Edward Z. Yang <ezyang@meta.com>
2024-11-09 22:02:09 -05:00
Edward Z. Yang
f16ace76cd chore: Disable 8.4 CI (#426) 2024-11-09 21:20:53 -05:00
semantic-release-bot
cb56001e54 chore(release): 4.18.0 [skip ci]
# [4.18.0](https://github.com/ezyang/htmlpurifier/compare/v4.17.0...v4.18.0) (2024-11-01)

### Bug Fixes

* Adjust Core.AllowHostnameUnderscore to consider that "_" is defined as Unreserved Characters in RFC 3986 ([#406](https://github.com/ezyang/htmlpurifier/issues/406)) ([d9fbef8](d9fbef8e27))
* Avoid a deprecated error when the attribute name is numeric and DirectLex is used ([#412](https://github.com/ezyang/htmlpurifier/issues/412)) ([f0fbf51](f0fbf51098))
* checking that node has property name ([#399](https://github.com/ezyang/htmlpurifier/issues/399)) ([9ca5a36](9ca5a3687b))
* Ignore conditional comments ([#401](https://github.com/ezyang/htmlpurifier/issues/401)) ([4828fdf](4828fdf45a))
* Support PHP 8.4 ([#396](https://github.com/ezyang/htmlpurifier/issues/396)) ([92da247](92da2473ff))
* undefined array key warning ([#419](https://github.com/ezyang/htmlpurifier/issues/419)) ([01be377](01be377f93))

### Features

* Add allowfullscreen attr for iframe ([#411](https://github.com/ezyang/htmlpurifier/issues/411)) ([70754a2](70754a2533))
* add directive for removing blank nodes ([#404](https://github.com/ezyang/htmlpurifier/issues/404)) ([c9d60c9](c9d60c96d7))
* Add support for CSS aspect-ratio ([#408](https://github.com/ezyang/htmlpurifier/issues/408)) ([93bee73](93bee73349))
* Allow universal CSS values for all properties ([#410](https://github.com/ezyang/htmlpurifier/issues/410)) ([9723267](972326785d))
2024-11-01 03:51:45 +00:00
Olek Kaim
01be377f93 fix: undefined array key warning (#419) 2024-10-30 22:57:29 -04:00
Atsushi Matsuo
f0fbf51098 fix: Avoid a deprecated error when the attribute name is numeric and DirectLex is used (#412) 2024-07-30 22:06:23 -04:00
John Flatness
70754a2533 feat: Add allowfullscreen attr for iframe (#411) 2024-06-30 07:54:09 -04:00
John Flatness
972326785d feat: Allow universal CSS values for all properties (#410) 2024-06-28 08:37:00 -04:00
Erik
93bee73349 feat: Add support for CSS aspect-ratio (#408) 2024-06-27 15:12:06 -04:00
Atsushi Matsuo
d9fbef8e27 fix: Adjust Core.AllowHostnameUnderscore to consider that "_" is defined as Unreserved Characters in RFC 3986 (#406) 2024-04-18 21:48:20 -04:00
charlie-curtis
c9d60c96d7 feat: add directive for removing blank nodes (#404) 2024-04-11 20:52:45 -04:00
Kent Oyer
4828fdf45a fix: Ignore conditional comments (#401) 2024-03-12 23:41:45 -04:00
Christian Castelli
9ca5a3687b fix: checking that node has property name (#399)
Co-authored-by: Christian Castelli <christian.castelli@docebo.com>
2024-03-05 10:58:42 -05:00
Edward Z. Yang
92da2473ff fix: Support PHP 8.4 (#396)
Signed-off-by: Edward Z. Yang <ezyang@meta.com>
2024-02-22 00:05:10 -05:00
semantic-release-bot
bbc513d79a chore(release): 4.17.0 [skip ci]
# [4.17.0](https://github.com/ezyang/htmlpurifier/compare/v4.16.0...v4.17.0) (2023-11-17)

### Bug Fixes

* CSSTidy ImportantComments not handled properly ([#359](https://github.com/ezyang/htmlpurifier/issues/359)) ([78a9b4d](78a9b4d0da))
* fix CI ([#361](https://github.com/ezyang/htmlpurifier/issues/361)) ([9ec687c](9ec687c904))
* Invalid scheme check in Attr.TargetBlank ([#363](https://github.com/ezyang/htmlpurifier/issues/363)) ([0176ef4](0176ef4bb6))
* semantic release ([#339](https://github.com/ezyang/htmlpurifier/issues/339)) ([d82f3d9](d82f3d996a))
* semantic release ([#341](https://github.com/ezyang/htmlpurifier/issues/341)) ([e55fead](e55fead09f)), closes [#339](https://github.com/ezyang/htmlpurifier/issues/339)
* Support for locales using decimal separators other than . (dot) ([#372](https://github.com/ezyang/htmlpurifier/issues/372)) ([43f49ac](43f49ac9a5))

### Features

* Add support for all text-decoration properties ([#360](https://github.com/ezyang/htmlpurifier/issues/360)) ([2d775c0](2d775c0187))
* Allows commas to be included in tel URI ([#389](https://github.com/ezyang/htmlpurifier/issues/389)) ([ec92490](ec92490139)), closes [#388](https://github.com/ezyang/htmlpurifier/issues/388)

### Reverts

* Revert "fix: semantic release (#339)" (#340) ([3e83215](3e832152a6)), closes [#339](https://github.com/ezyang/htmlpurifier/issues/339) [#340](https://github.com/ezyang/htmlpurifier/issues/340)
2023-11-17 15:01:25 +00:00
Edward Z. Yang
0f0fd36896 ci: upgrade semantic-release-action
Signed-off-by: Edward Z. Yang <ezyang@meta.com>
2023-11-17 10:00:42 -05:00
danbrellis
ec92490139 feat: Allows commas to be included in tel URI (#389)
* Allows commas in tel URI scheme validator (addresses #388)

* Adds comment explaining 8429f7b
2023-11-10 10:25:42 -05:00
Tim Düsterhus
ab21ea735a chore: Add support for PHP 8.3 (#382)
* Add PHP 8.3 to CI

* Allow PHP 8.3 in composer.json
2023-08-24 11:15:30 -04:00
Edward Z. Yang
6eb6123036 Don't suggest chmod to 777 (#373)
Signed-off-by: Edward Z. Yang <ezyang@meta.com>
2023-04-30 13:55:11 -04:00
cracksalad
43f49ac9a5 fix: Support for locales using decimal separators other than . (dot) (#372)
* Bugfix UnitConverter expects float got string (strict types enabled)

* Bugfix for latest bugfix with huge numbers

* Bugfix for german locale

* Use number_format instead of str_replace(sprintf())
2023-04-30 09:30:23 -04:00
George Peter Banyard
c05639e0c9 [refactor] Use range() function instead of string increment (#367)
This was found during the analysis for https://wiki.php.net/rfc/saner-inc-dec-operators

I don't know what is the minimal version targeted, so the line which defines ``$c`` may need to be changes to use ``array_merge()``
2023-02-23 13:11:13 -05:00
Steve Bauman
b4136da73c Remove unnecessary disablement of autoload (#364) 2023-02-05 21:40:57 -05:00
Jeff Standen
0176ef4bb6 fix: Invalid scheme check in Attr.TargetBlank (#363) 2023-01-26 19:06:28 -05:00
Francis Lévesque
78a9b4d0da fix: CSSTidy ImportantComments not handled properly (#359)
* fix: CSSTidy ImportantComments not handled properly

Signed-off-by: Francis Lévesque <wolfrank2164@gmail.com>

* fix: CSSTidy ImportantComments not handled properly -> remove comments

Signed-off-by: Francis Lévesque <wolfrank2164@gmail.com>
Co-authored-by: Edward Z. Yang <ezyang@meta.com>
2023-01-21 22:44:44 -05:00
Edward Z. Yang
9ec687c904 fix: fix CI (#361)
Signed-off-by: Edward Z. Yang <ezyang@meta.com>

Signed-off-by: Edward Z. Yang <ezyang@meta.com>
2023-01-21 22:42:38 -05:00
Raheel Hsn
2d775c0187 feat: Add support for all text-decoration properties (#360)
* CSS: add support for all text-decoration related properties

* updated arrays to use short syntex

Co-authored-by: Raheel Hasan <raheel.hasan@luciditysoftware.com.au>
2023-01-12 08:41:13 -05:00
jw2(kit rio)
da35a5e0d7 Drop supporting PHP 5.2 (#335) (#356) 2022-12-04 13:22:17 -06:00
Michael S
1424f17cf3 Add support for encoded tel URI schemes. (#354) 2022-11-24 16:31:20 -05:00
Michael Kliewe
becc9d40cf Fixed missing return value (#349) 2022-11-19 14:26:34 -08:00
Michael Kliewe
909dda6621 Fixed wrong return PHPDoc (#348) 2022-11-18 21:03:18 -08:00
Michael Kliewe
2d1314820e Added class_exists('Net_IDNA2') around optional external class (#351) 2022-11-18 20:56:21 -08:00
Michael Kliewe
d567de85e6 Fixed undefined property (#346) 2022-11-18 20:42:06 -08:00
Kieran
e55fead09f fix: semantic release (#341)
Same as #339 but stops library/standalone and library/HTMLPurifier.standalone.phpfrom being commit
2022-09-20 12:45:11 -04:00
Edward Z. Yang
3e832152a6 Revert "fix: semantic release (#339)" (#340)
This reverts commit d82f3d996a.
2022-09-18 15:21:20 -04:00
Kieran
d82f3d996a fix: semantic release (#339)
* fix: semantic release

* update git assets
2022-09-18 15:15:38 -04:00
semantic-release-bot
523407fb06 chore(release): 4.16.0 [skip ci]
# [4.16.0](https://github.com/ezyang/htmlpurifier/compare/v4.15.0...v4.16.0) (2022-09-18)

### Features

* add semantic release ([#307](https://github.com/ezyang/htmlpurifier/issues/307)) ([db31243](db312435cb)), closes [#322](https://github.com/ezyang/htmlpurifier/issues/322) [#323](https://github.com/ezyang/htmlpurifier/issues/323) [#326](https://github.com/ezyang/htmlpurifier/issues/326) [#327](https://github.com/ezyang/htmlpurifier/issues/327) [#328](https://github.com/ezyang/htmlpurifier/issues/328) [#329](https://github.com/ezyang/htmlpurifier/issues/329) [#330](https://github.com/ezyang/htmlpurifier/issues/330) [#331](https://github.com/ezyang/htmlpurifier/issues/331) [#332](https://github.com/ezyang/htmlpurifier/issues/332) [#333](https://github.com/ezyang/htmlpurifier/issues/333) [#337](https://github.com/ezyang/htmlpurifier/issues/337) [#335](https://github.com/ezyang/htmlpurifier/issues/335) [ezyang/htmlpurifier#334](https://github.com/ezyang/htmlpurifier/issues/334) [#336](https://github.com/ezyang/htmlpurifier/issues/336) [#338](https://github.com/ezyang/htmlpurifier/issues/338)
2022-09-18 07:06:19 +00:00
Kieran
db312435cb feat: add semantic release (#307)
* Add semantic release

* fix typo

* split from matrix

* remove only on push

* remove npm plugin

* write changelog to NEWS

* list assets to include in git commit

* fix update-for-release

* lint pr title

* split release into separate workflow that runs manually

* revert ci.yml changes

* remove references to WHATSNEW

* Fix #322 - PHP 8.1 deprecation notice in HostBlacklist URIFilter (#323)

* Replace 8.1-deprecated utf8_ funcs with mbstring (#326)

* Treat PHP version numbers as strings in GitHub Actions (#327)

YAML will try to interpret numeric values as numbers, leading to `8.0` being
interpreted as `8` instead of `'8.0'`.

This doesn't result in a functional change, but cleans up the output of the
jobs a little (e.g. in the title line).

* Update to `actions/checkout@v3` (#328)

This does not introduce any functional difference and is intended as a
future-proofing change.

see https://github.com/actions/checkout/releases/tag/v3.0.0

* Fix test selection logic in tests/test_files.php (#329)

Selecting the `fstools` tests also executed the `htmlt` tests.

* Fix some more PHP 8.2 deprecations (#330)

* Define HTMLPurifier_AttrTransform_SafeParam::$wmode

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_DefinitionCache_DecoratorHarness::$cache

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_DefinitionCache_DecoratorHarness::$mock

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_DefinitionCache_DecoratorHarness::$def

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_EntityParserTest::$_entity_lookup

This fixes a PHP 8.2 deprecation.

* Increase minimum requirement to PHP 5.6 (#331)

* Add contenteditable attribute definition (#332)

* Add contenteditable attribute definition

* gate behind html.trusted

* use enum

* Fix creation of dynamic property (#333)

* Fix creation of dynamic property (#337)

* Add PHP 8.2 to CI (#335)

* Add PHP 8.2 to CI

see ezyang/htmlpurifier#334

* Add PHP 8.2 to composer.json

* Fix contenteditable attribute definition (#336)

* Run CSSTidy tests on CI (#338)

* Run CSSTidy tests on CI

* update dirname

* use compopser instead of git clone

* use composer

* use test-settings.sample.php

* enable ext-intl

* disable Net_IDNA2

* Release 4.15.0

Signed-off-by: Edward Z. Yang <ezyang@mit.edu>

Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
Co-authored-by: John Flatness <john@zerocrates.org>
Co-authored-by: Tim Düsterhus <duesterhus@woltlab.com>
Co-authored-by: Tim Düsterhus <timwolla@googlemail.com>
Co-authored-by: Edward Z. Yang <ezyang@mit.edu>
2022-09-18 02:44:00 -04:00
Edward Z. Yang
8d9f4c9ec1 Release 4.15.0
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2022-09-18 02:23:57 -04:00
Kieran
25824056ee Run CSSTidy tests on CI (#338)
* Run CSSTidy tests on CI

* update dirname

* use compopser instead of git clone

* use composer

* use test-settings.sample.php

* enable ext-intl

* disable Net_IDNA2
2022-09-14 20:55:41 -07:00
Kieran
f1d6da13bc Fix contenteditable attribute definition (#336) 2022-09-12 07:53:24 -07:00
Tim Düsterhus
dc27c78871 Add PHP 8.2 to CI (#335)
* Add PHP 8.2 to CI

see ezyang/htmlpurifier#334

* Add PHP 8.2 to composer.json
2022-09-11 19:51:02 -04:00
Kieran
ce9cf2ec99 Fix creation of dynamic property (#337) 2022-09-10 14:03:42 -04:00
Kieran
36e06603a8 Fix creation of dynamic property (#333) 2022-09-06 13:05:15 -04:00
Kieran
dbbd3e59f9 Add contenteditable attribute definition (#332)
* Add contenteditable attribute definition

* gate behind html.trusted

* use enum
2022-09-06 13:04:45 -04:00
Tim Düsterhus
1c2bae18e3 Increase minimum requirement to PHP 5.6 (#331) 2022-09-02 21:43:29 -04:00
Tim Düsterhus
1b80051115 Fix some more PHP 8.2 deprecations (#330)
* Define HTMLPurifier_AttrTransform_SafeParam::$wmode

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_DefinitionCache_DecoratorHarness::$cache

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_DefinitionCache_DecoratorHarness::$mock

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_DefinitionCache_DecoratorHarness::$def

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_EntityParserTest::$_entity_lookup

This fixes a PHP 8.2 deprecation.
2022-09-02 21:38:58 -04:00
Tim Düsterhus
c60bba1fe4 Fix test selection logic in tests/test_files.php (#329)
Selecting the `fstools` tests also executed the `htmlt` tests.
2022-09-02 21:35:32 -04:00
Tim Düsterhus
6ec13635ce Update to actions/checkout@v3 (#328)
This does not introduce any functional difference and is intended as a
future-proofing change.

see https://github.com/actions/checkout/releases/tag/v3.0.0
2022-08-30 09:50:18 -04:00
Tim Düsterhus
be2a668e81 Treat PHP version numbers as strings in GitHub Actions (#327)
YAML will try to interpret numeric values as numbers, leading to `8.0` being
interpreted as `8` instead of `'8.0'`.

This doesn't result in a functional change, but cleans up the output of the
jobs a little (e.g. in the title line).
2022-08-30 09:46:59 -04:00
John Flatness
dff4746e13 Replace 8.1-deprecated utf8_ funcs with mbstring (#326) 2022-08-15 22:59:31 -04:00
Kieran
3fc193c755 Fix #322 - PHP 8.1 deprecation notice in HostBlacklist URIFilter (#323) 2022-06-27 17:20:36 -04:00
Tim Düsterhus
1db36fb09d Fix some PHP 8.2 deprecations (#319)
* Define HTMLPurifier_Lexer::$_entity_parser property

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_URIFilterHarness::$filter property

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_AttrTransform_NameSync::$idDef property

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_AttrTransform_NameSyncTest::$accumulator property

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_AttrValidator_ErrorsTest::$language property

This fixes a PHP 8.2 deprecation.

* Define HTMLPurifier_ChildDef_List::$whitespace property

This fixes a PHP 8.2 deprecation.

* Do not modify incoming tokens in RemoveSpansWithoutAttributes

Previously the undefined property `->markForDeletion` was added to the incoming
tokens. This causes a deprecation in PHP 8.2. Fix this by storing to-be-deleted
tokens inside SplObjectStorage. In PHP 8 a WeakMap would be preferable, as that
prevents leaks if `handleEnd` is never called for the token.
2022-06-10 16:30:01 -04:00
func0der
38296c603b Composer suggestions with extensions (#317)
* Add suggestion for usage of Filter.ExtractStyleBlocks

Resolves #316

* Add php extensions as suggestions

Resolves #316

* Correct typo in composer property
2022-06-02 23:03:44 -04:00
David Rans
1dd3e52365 PHP 8.1: fix various deprecations/errors in newest version of PHP (#310)
* Test on PHP 8.1

* PHP 8.1: fix deprecated NULL param to glob()

* PHP 8.1: fix PHP error when passing NULL to rawurlencode()

* PHP 8.1: calling ctype_lower with FALSE is deprecated

* PHP 8.1: passing NULL to setAttribute() is deprecated

* PHP 8.1: passing NULL to str_replace() is an error

* PHP 8.1: fix error passing NULL to str_replace()

* PHP 8.1: fix return type deprecation with backwards compatible attribute

* Revert typo
2022-04-08 13:48:12 -04:00
Edward Z. Yang
12ab42bd6e Release 4.14.0
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2021-12-24 20:21:49 -05:00
Kieran
1c784a5c3d ci: test on php 8.0 (#308)
* PHP 8 support

* only php 8.0

* Merged to master

Co-authored-by: Edward Z. Yang <ezyang@mit.edu>
2021-12-23 21:26:25 -05:00
Kieran
41fc223f96 feat: transform deprecated width attribute (#306)
* Transform deprecated col@width attribute

* Transform deprecated table@width attribute

* reformat
2021-12-23 21:26:14 -05:00
Arkadiusz Biczewski
996eaf4331 Remove unnecessary reference assigment (#301)
* Remove unnecessary reference assigment

Proposed code is PHP5 and PHP7 compatible. PHP5 interpreted `$e->$type[$attr]` as `$e->{$type[$attr]}`, but the expected behavior based on workaround is consistent with PHP7 interpretation: `($e->$type)[$attr]`. By using curly braces `{$e->$type}[$attr]` there is a forced interpretation order working for both versions.
Details can be found on https://www.php.net/manual/en/migration70.incompatible.php (section "Changes to the handling of indirect variables, properties, and methods")

* Fix syntax

Use correct syntax for indirect variable evaluation order change.
2021-09-07 14:16:55 -04:00
Kieran
c97bb93223 Fix GH workflow conditions (#298)
* Fix GH workflow conditions

* Remove PHP 8
2021-07-26 10:16:49 -04:00
Max
288bf75acc PHP 8 Support (#297)
Co-authored-by: Maksims Sļotovs <maksims.slotovs@printful.com>
2021-07-20 09:40:50 -04:00
Kieran
3a368d7668 Switch to GitHub Actions (#293) 2021-05-21 20:46:13 -04:00
Václav Smítal
6f9aac9325 CSS: Add "background-size" tag support (#289) 2021-04-22 10:01:00 -04:00
Kieran
1354e7e8c5 Fix "Parameter must be an array or an object that implements Countable" (#285) 2021-02-27 20:42:20 -05:00
Marcus Artner
214cb8a693 Fixed Issue #264: <thead> element removed from <table> if there are no <tbody> or <tr> elements (#283) 2021-01-26 11:11:50 -05:00
Jasper Zonneveld
2512f595e0 Check PHP version before checking magic quotes (#273)
This function has been DEPRECATED as of PHP 7.4.0. Relying on this function is highly discouraged. It is basically useless as of PHP 5.4 because it will always return false, so for modern applications it can be safely removed. But as this library still supports PHP 5.2 — according to the constraints in composer.json — I added a version check to prevent this method from being called (and trigger a notice) on PHP >=7.4.

See: https://www.php.net/manual/en/function.get-magic-quotes-gpc.php
2020-09-30 20:19:10 -04:00
kishor
6aa4166b7e Issue-256: Fix PHP 7.3 compatibility issues update zend.ze1_compatibility_mode mode (#267) 2020-09-15 20:12:43 -04:00
kishor
4285590c90 issue-256: Fix PHP 7.3 compatibility issues (#266) 2020-09-15 12:38:39 -04:00
LeSuisse
15258fd24e Fix typo in the 4.13.0 NEWS: PHP 6.4 never existed (#262)
Corresponding PRs (#230, #242) are about PHP 7.4 and PHP 6.4 has never
existed 🙂.
2020-07-06 14:36:33 -04:00
Edward Z. Yang
08e27c97e4 Release 4.13.0
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2020-06-28 20:56:53 -04:00
Edward Z. Yang
d7be9d2a8c Update changelog
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2020-06-28 20:55:45 -04:00
Edward Z. Yang
ce7efc11b2 Delete language tests that are interfering with PSR-0 compatibility
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2020-06-28 20:38:16 -04:00
Mateusz Turcza
3bdc031224 Add %HTML.Forms config directive (#260)
The %HTML.Forms directive enables Forms module regardless of the %HTML.Trusted
value. This adds support for form elements without enabling other unsafe
modules, such as Scripts, Iframe or Object.

To achieve the same effect without this directive one has to explicitly list
all enabled modules in %HTML.AllowedModules, and any not listed will be
removed. This however is not very convenient, as the allowed modules may vary
between doctypes.

Resolves #213.
2020-06-28 20:26:33 -04:00
Sergei Morozov
d148edbcf1 Exclude more resources from the distribution package (#257) 2020-06-06 10:29:01 -04:00
Fräntz Miccoli
ced089434d Make purifyArray work with empty array (#245) 2020-02-22 12:12:02 -05:00
Kieran
c2c91f52d0 Added tr@bgcolor to tidy (#244) 2020-02-22 12:10:30 -05:00
Eloy Lafuente
37dd61c45f Correct implode() params for php74 compliance (#243)
Passing parameters to implode() in reverse order is deprecated, use
implode($glue, $parts) instead of implode($parts, $glue).

Part of https://tracker.moodle.org/browse/MDL-67115
2020-01-21 11:17:18 -05:00
Witold Wasiczko
d15890222b Add support for stable php 7.4 (#242) 2020-01-02 06:58:15 -05:00
Anders Jenbo
fe0452d688 Correct typehinting of maybeGet* (#240)
getDefinition can return null, this wasn't properly hinted leaning to false error detections with static analyzers
2019-12-04 10:29:08 -05:00
lubomirbartos
df923d1f15 Issue 238 remove leading zeroes except if there is only zero (#239)
* Issue 238 remove leading zeroes except if there is only zero

* Issue-238 unit test fixes
2019-11-21 10:05:07 -05:00
Jordi Boggiano
4faca32a4d Exclude language classes from autoloader optimization (#236)
These classes are autoloaded by a custom autoloader
2019-10-31 13:42:00 -04:00
Edward Z. Yang
a617e55bc6 Release 4.12.0
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2019-10-27 23:44:26 -04:00
Edward Z. Yang
3060a5606c Update changelog
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2019-10-27 23:42:45 -04:00
Edward Z. Yang
b4ec8c8036 Merge remote-tracking branch 'ezyang/master' 2019-10-27 23:40:25 -04:00
Mateusz Turcza
06b3fc4cf4 Fix phpdoc params in HTMLModule::addElement() and Bool attr (#233) 2019-10-25 10:07:38 -04:00
Witold Wasiczko
c6ca293eab Add support for PHP 7.4 (#230)
* Add php7.4

* 7.4 cannot fail

* Disallow failures
2019-09-11 20:25:44 -04:00
Mateusz Turcza
ab2887e423 Fix DOM Lexer for PHP versions older than 5.4 (#225) 2019-08-09 17:01:13 -04:00
Mateusz Turcza
029d1df5e3 Fix PHP 5.4 and 5.5 builds on Travis CI (#227) 2019-08-09 09:45:41 -04:00
Edi Modrić
b88fcd180c Replace curly braces with square brackets in string offsets (#224) 2019-07-30 22:50:43 -04:00
Edward Z. Yang
83ab08bc1a Release 4.11.0
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2019-07-14 14:58:38 -04:00
Edward Z. Yang
2739fa5462 Update changelog.
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2019-07-14 14:22:14 -04:00
Sandro Miguel Marques
b91833877a Method purifyArray() updated (#143)
* Methof purifyArray() updated

Now it works with multidimensional arrays

* Add test case.

Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2019-07-14 14:10:33 -04:00
Edward Z. Yang
abba77a80b Recent PHPs default to display_error=0, override this in index.php
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2019-07-14 14:04:12 -04:00
Michael Kliewe
7cfc44654a CSS: added "initial" and "inherit" to width + height (#144)
* CSS: added "initial" and "inherit" to width + height
CSS: added "initial" and "inherit" to min-width + min-height, removed "auto"
CSS: added "initial" and "inherit" and "none" to max-width + max-height, removed "auto"

* Fixed test: min-width:auto; should be false
2019-07-14 13:20:58 -04:00
msuzuki
8c153eef3a Supported hundreds of nested HTML (#202)
* Supported hundreds of nested HTML (#201)

* Add Core.AllowParseManyTags
2019-07-14 13:15:31 -04:00
DiLong Fa
524cd08a59 Update Config.php (#211)
Fixed Undefined index: class
2019-07-14 13:11:34 -04:00
Lukas Neumann
5a90c92d83 Adds PHP 7.3 to Travis (#214)
* Adds PHP 7.3 to Travis

* Fix tests for PHP 7.3
2019-07-14 13:10:24 -04:00
Darko Hrgovic
f03e1a2c48 Fixed reserved words in constants for PHP 7 as per https://www.php.net/manual/en/reserved.other-reserved-words.php (#222) 2019-07-10 22:24:27 -04:00
Edward Z. Yang
a93250f251 Don't use @ warning suppression.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 18:20:33 -05:00
Edward Z. Yang
5a8e48d672 Remove php extension from release1-update script, to appease #192
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 17:05:51 -05:00
Edward Z. Yang
cb5a742574 Replace flush.php with a shell script, to appease #192
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 17:04:11 -05:00
Edward Z. Yang
ff41146439 Delete defunct release2-tag.php script.
Thanks Adham Saad <asaad@edrnet.com> for reporting.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 16:59:24 -05:00
Edward Z. Yang
aa83689188 Delete references to PHP 5.1 in INSTALL.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 16:56:06 -05:00
Edward Z. Yang
3d15f5253b Don't define __autoload; rely on spl_autoload_register
Fixes #196

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 16:55:01 -05:00
Edward Z. Yang
21e32042e9 Update schema for case-sensitive safe scripting
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 16:54:33 -05:00
Edward Z. Yang
ce0ccc4bff Delete unneeded update-config.php script
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 16:54:33 -05:00
Chris Pelzer
ab7bbefe8a Update reference to the valid types to refer to HTMLPurifier_VarParser::types (#189) 2018-11-11 16:23:01 -05:00
Edward Z. Yang
0f7b138aaf Make SafeScripting case-sensitive.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 16:21:58 -05:00
Edward Z. Yang
4b6b3b31e8 Typofix: AutoForamt -> AutoFormat
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-11-11 16:21:58 -05:00
Dimitri Gritsajuk
5a01e6535d [SafeScripting] disable autoclosing of <script /> tag (#198) 2018-11-11 15:04:11 -05:00
Benjamin Brahmer
b74425bee5 .htaccess support apache 2.4+ (#190) 2018-11-11 14:55:13 -05:00
Oleg Kainov
39068e6d08 Update PHP version in INSTALL (#195)
* update PHP version in INSTALL

Fix #194

* update PHP version in INSTALL

Fix #194
2018-10-23 20:03:41 -04:00
Daijobou
b81690c17e More colors names (#176)
Added more colors names https://www.w3schools.com/colors/colors_names.asp

remove old unorded colors names
2018-06-09 22:48:13 -04:00
Mathias Brodala
4005ffd563 Suggest stable Composer installation (#179)
Normally people should not use the latest master but the latest stable release instead.
2018-06-09 22:44:20 -04:00
Mateusz Turcza
89b3fe431e Use IDNA constants only if defined (#171)
Fixes #168.

Solution based on https://git.ispconfig.org/ispconfig/ispconfig3/commit/0e3cf6f51b4fd.
2018-03-04 19:16:11 -05:00
Mateusz Turcza
3cb77da11d Make tagName and node data detection hhvm compatible (#170) 2018-03-04 13:22:03 -05:00
Edward Z. Yang
c1167edbf1 dummy commit
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-02-22 21:36:54 -05:00
Edward Z. Yang
c7b5148c4f New changelog entry.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-02-22 21:34:16 -05:00
Edward Z. Yang
f8c830de12 Fix SPDX identifier
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-02-22 21:26:02 -05:00
Edward Z. Yang
0737a6e916 Whoops, forgot to edit WHATSNEW
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-02-22 21:07:33 -05:00
Edward Z. Yang
d85d39da45 Release 4.10.0
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-02-22 20:58:20 -05:00
Edward Z. Yang
f33d1f8e99 Changelog prep for release. (#167)
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2018-02-22 20:55:01 -05:00
John Flatness
6d6d88512a Skip counting currentNesting if null
This is an error starting in PHP 7.2
2017-12-30 00:23:44 -05:00
John Flatness
bb7ad66526 Quarantine __autoload defs for PHP 7.2 compat 2017-12-30 00:23:05 -05:00
Edward Z. Yang
64baeda65c Deal with old libxml incompatibilities.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-12-22 22:03:02 -05:00
Jan Dageförde
67c3798922 Add relative length units from CSS 3
cf. https://www.w3schools.com/cssref/css_units.asp
2017-12-22 21:59:47 -05:00
Brad Mostert
df64746caa Fix spelling 2017-12-22 21:59:19 -05:00
Roberto
ab9c9f30fd Small typos in comments 2017-12-13 11:16:39 -05:00
Edward Z. Yang
5988f29583 Remove PHP 5.3 support.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-10-08 19:52:05 -04:00
Marina Glancy
ce0ede24de Use IDNA2008 for converting domains to ASCII 2017-10-03 11:19:50 -04:00
Edward Z. Yang
17f80cd74b Merge pull request #141 from pawelkania/master
Fix E_WARNING when cache directory exists
2017-06-23 22:50:48 -04:00
pawelkania
e11f7c9802 Fix E_WARNING when cache directory exists
Sometimes Serializer from another thread already creaded dir - this commit resolves this issue.
2017-06-20 09:53:14 +02:00
Edward Z. Yang
d21213e0d3 Merge pull request #139 from Edgars-Burtnieks/patch-1
Unnecessary space which gives error removed
2017-06-10 15:57:51 -04:00
Edgars-Burtnieks
9b3f856fb9 Update README.md 2017-06-10 22:36:19 +03:00
Edward Z. Yang
95e1bae318 Release 4.9.3
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-06-02 22:28:16 -04:00
Edward Z. Yang
ff16ed3de4 Merge pull request #137 from Xiphin/master
Fix: using null instead of false. Fixed CPU is 100% on PHP 7.1.*
2017-06-02 21:07:56 -04:00
Xiphin
1df505296f Mod: using stdClass instead of stdclass 2017-06-02 09:55:46 +08:00
Xiphin
b9bc1039da Mod: using null instead of false 2017-06-02 08:50:38 +08:00
Xiphin
cb4871f446 Fix: It runs on PHP 7.1.* CPU process is 100% 2017-06-01 21:32:25 +08:00
Edward Z. Yang
65d5cdee50 Merge pull request #130 from Izumi-kun/lexer-create-fix
Autoloading must be skipped while checking for php builtin class.
2017-03-21 17:50:26 -07:00
Viktor Khokhryakov
b45c6f5363 Autoloading must be skipped while checking for php builtin class. 2017-03-20 10:42:28 +04:00
Edward Z. Yang
6d50e5282a Release 4.9.2
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-12 23:30:53 -07:00
Edward Z. Yang
5bc7c72608 Add tests for new entity decoding codepath.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-12 20:05:09 -07:00
Edward Z. Yang
98984546d4 NEWS for 4.9.2
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-12 20:03:47 -07:00
Edward Z. Yang
c7a2f6f0df Merge pull request #129 from rybakit/patch-1
Fix a call to undefined function HTMLPurifier_Encoder()
2017-03-12 16:25:58 -07:00
Eugene Leonovich
fd24de69a3 Fix a call to undefined function HTMLPurifier_Encoder() 2017-03-12 22:44:03 +01:00
Edward Z. Yang
5688656174 Fix more PHP 5.3 problems.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-08 18:01:58 -08:00
Edward Z. Yang
d728205767 Turn on 5.3 Travis testing.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-08 17:47:14 -08:00
Edward Z. Yang
8836ae05aa Fix PHP 5.3 compatibility, fixes #125.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-08 17:46:29 -08:00
Edward Z. Yang
b90295deda Enable PHP 7.1 testing.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-08 13:38:20 -08:00
Edward Z. Yang
de82f9845f Release 4.9.1 (sic)
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-08 00:22:36 -08:00
Edward Z. Yang
9d2d75d8bc Add test case for removing empty list items.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-08 00:11:32 -08:00
Edward Z. Yang
74f123a84c Fix #83.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-07 17:52:41 -08:00
Edward Z. Yang
7e11c271b9 Revamp entity decoding to be more like HTML5.
See %Core.LegacyEntityDecoder for more details.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-07 17:34:59 -08:00
Edward Z. Yang
66bbae73a9 Comment on why it's a non-greedy match.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-06 23:27:30 -08:00
Edward Z. Yang
5886326cd0 Test for catastrophic backtracking.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-06 23:26:55 -08:00
Edward Z. Yang
564af61809 Usage/includes update.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-06 23:06:56 -08:00
Edward Z. Yang
b19dcb0ba5 CHANGELOG for #120 fix, and remove the array_filter.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-06 23:06:24 -08:00
Edward Z. Yang
586abc63e4 CHANGELOG for rgba/hsl/hsla patch.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-06 23:03:33 -08:00
Edward Z. Yang
5b6a3f55bf Merge pull request #121 from breathbath/master
Fixing PREG_BACKTRACK_LIMIT_ERROR in HTMLPurifier_Filter_ExtractStyle…
2017-03-06 23:01:34 -08:00
Edward Z. Yang
0c31b22240 Merge pull request #118 from fxbt/master
Add hsl, hsla and rgba support for css color attribute definition
2017-03-06 23:01:06 -08:00
Edward Z. Yang
5662efc936 Fix #78.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-06 22:54:54 -08:00
Edward Z. Yang
353c96f156 Document skips in more detail, #116.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-06 20:31:28 -08:00
Edward Z. Yang
4047a6230b Extra cleanup on cleanUTF8.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-03-06 16:31:02 -08:00
Andrey Pozolotin
9195cb7a2e Added escape sequense 2017-03-06 16:28:53 -08:00
Andrey Pozolotin
39c4c359ad Fixing PREG_BACKTRACK_LIMIT_ERROR in HTMLPurifier_Filter_ExtractStyleBlocks 2017-03-06 16:28:53 -08:00
Edward Z. Yang
bb3f86e80a Merge pull request #123 from mpyw-forks/fix/#122/surrogate-pair-range
Fix surrogate pair range
2017-03-03 23:13:30 -08:00
mpyw
d16e73e63e Add test for #122 2017-03-04 15:40:44 +09:00
mpyw
f145f64bf4 Fix #122: correct surrogate pair range 2017-03-04 15:38:01 +09:00
Andrey Pozolotin
5fdec87fe9 Added escape sequense 2017-03-01 17:52:00 +01:00
Andrey Pozolotin
4462559459 Fixing PREG_BACKTRACK_LIMIT_ERROR in HTMLPurifier_Filter_ExtractStyleBlocks 2017-03-01 17:46:03 +01:00
f.godfrin
12185143ef Use a constructor and a property for the alpha check 2017-02-10 21:03:11 +01:00
f.godfrin
17a90a951a Better regex for mungeRgb 2017-02-10 00:40:56 +01:00
f.godfrin
0bab4b9fd0 Fix mungeRgb to handle percent, float and hsl values 2017-02-10 00:38:05 +01:00
f.godfrin
bd92f3531b Remove double % 2017-02-09 23:37:36 +01:00
f.godfrin
0d5ab2fe13 Include hsl and hsla support 2017-02-09 23:34:19 +01:00
f.godfrin
d41a59e422 Add rgba support for css color attribute definition 2017-02-09 22:18:15 +01:00
Bastian Hofmann
8e4cacf0a7 Refactor HTML.Noopener to HTML.TargetNoopener so that it behaves like HTML.TargetNoreferrer and is active by default if a target is set 2017-02-03 16:54:51 -08:00
Bastian Hofmann
c82051c3e1 Add HTML.Noopener to add a noopener rel to every external link
This has performance benefits https://jakearchibald.com/2016/performance-benefits-of-rel-noopener/ but most importantly also security benefits https://mathiasbynens.github.io/rel-noopener/

Adresses https://github.com/ezyang/htmlpurifier/issues/96
2017-02-03 16:54:51 -08:00
Edward Z. Yang
d4a96463ef export-ignore .travis.yml
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-01-19 09:28:40 -08:00
Edward Z. Yang
1b7d684d07 Remove $a = array($a) which is miscompiled by Zend OpCache.
Fixes #108.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2017-01-04 14:35:52 -05:00
Edward Z. Yang
5070404376 Handle semicolons in strings in CSS correctly.
Fixes http://htmlpurifier.org/phorum/read.php?3,7522,8096

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-29 00:01:19 -07:00
Edward Z. Yang
cef27f750d Add missing changelog entries.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-27 17:31:10 -07:00
Edward Z. Yang
59463c5c39 Allow %URI.DefaultScheme to be null.
Fixes #103.

Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-27 17:30:44 -07:00
Edward Z. Yang
d19d648a26 [ci skip] Add a Travis build badge.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-27 02:02:29 -07:00
Edward Z. Yang
20b40a5441 Travis support.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-27 02:00:47 -07:00
Edward Z. Yang
34d252cbbc Update usage.xml.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-27 02:00:47 -07:00
Edward Z. Yang
8b28e571fe Handle case when IDNAs are supported.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-27 02:00:46 -07:00
Edward Z. Yang
3ae21ce511 PHP 7.0 warnings fix: don't pass rvalue by reference.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-27 02:00:46 -07:00
Edward Z. Yang
3ba9133b21 Don't assume that idn_to_ascii does validation.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-27 02:00:46 -07:00
Edward Z. Yang
dc8702160c Merge pull request #101 from yankos/hotfix/directory_not_close
FIX directory not closing
2016-10-15 23:14:10 -07:00
yan_kos
4dc68aa920 FIX directory not closing
#100
2016-10-15 16:20:47 +03:00
Edward Z. Yang
08eee90e15 Delete asserts, fixes #97.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-10-02 00:14:41 -07:00
Edward Z. Yang
1ef4375dbb Proposed fix to Serializer code.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
2016-09-05 15:24:08 -07:00
Edward Z. Yang
6a221a3045 Merge pull request #94 from zobzn/css-min-max-width
css definition (min-width, max-width, min-height, max-height)
2016-09-05 14:57:44 -07:00
zema
246fc8946a css properties: min-width, max-width, min-height, max-height 2016-09-05 10:45:58 +03:00
Edward Z. Yang
1ce2fde400 Merge pull request #91 from apsdsm/fix-permissions-bug
changed chmod behaviour in Serializer
2016-07-29 03:25:41 -07:00
Nick del Pozo
1f982d279f rollback change to permissions 2016-07-29 08:56:36 +09:00
Nick del Pozo
8be8cee9b3 changed chmod behaviour in Serializer 2016-07-27 12:56:03 +09:00
219 changed files with 2874 additions and 1192 deletions

31
.gitattributes vendored
View File

@@ -1,12 +1,25 @@
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/Doxyfile export-ignore
/art/ export-ignore
/benchmarks/ export-ignore
/configdoc/ export-ignore
/art export-ignore
/benchmarks export-ignore
/configdoc export-ignore
/configdoc/usage.xml -crlf
/docs/ export-ignore
/phpdoc.ini
/smoketests/ export-ignore
/tests/* export-ignore
/tests/path2class.func.php -export-ignore
/docker-compose.yaml export-ignore
/Dockerfile export-ignore
/docs export-ignore
/Doxyfile export-ignore
/extras export-ignore
/INSTALL* export-ignore
/maintenance export-ignore
/NEWS export-ignore
/package.php export-ignore
/plugins export-ignore
/phpdoc.ini export-ignore
/smoketests export-ignore
/test-* export-ignore
/tests export-ignore
/TODO export-ignore
/update-for-release export-ignore
/WYSIWYG export-ignore
/release.config.js export-ignore

36
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,36 @@
name: ci
on:
push:
pull_request:
jobs:
linux_tests:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5']
name: PHP ${{ matrix.php }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
tools: composer:v2
ini-values: error_reporting=E_ALL
extensions: iconv, bcmath, tidy, mbstring, intl
- name: Install dependencies
run: composer install
- name: Configure simpletest
run: cp test-settings.sample.php test-settings.php
- name: Execute Unit tests
run: php tests/index.php

19
.github/workflows/lint-pr.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: "Lint PR"
on:
pull_request_target:
types:
- opened
- edited
- synchronize
jobs:
main:
name: Validate PR title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

29
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: release
on:
workflow_dispatch:
jobs:
release:
runs-on: ubuntu-latest
name: Release
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
- name: Run automated release process with semantic-release
uses: cycjimmy/semantic-release-action@v4
with:
extra_plugins: |
@semantic-release/changelog
@semantic-release/git
@semantic-release/exec
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View File

@@ -26,3 +26,4 @@ composer.lock
*.orig
*.bak
core
.idea

30
Dockerfile Normal file
View File

@@ -0,0 +1,30 @@
FROM ubuntu:24.04
ARG DEBIAN_FRONTEND=noninteractive
ENV PHP_VERSION="8.4"
ENV LANG en_US.UTF-8
ENV LC_ALL en_US.UTF-8
RUN apt update -y && apt -y install git curl locales doxygen software-properties-common
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen en_US.UTF-8 && \
update-locale LANG=en_US.UTF-8 \
RUN echo -y | add-apt-repository ppa:ondrej/php && apt update -y
RUN apt install -y \
php${PHP_VERSION} \
php${PHP_VERSION}-dev \
php${PHP_VERSION}-xdebug \
php${PHP_VERSION}-iconv \
php${PHP_VERSION}-bcmath \
php${PHP_VERSION}-tidy \
php${PHP_VERSION}-xml
RUN echo "xdebug.mode=debug,coverage" >> /etc/php/${PHP_VERSION}/cli/php.ini
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /opt/htmlpurifier

View File

@@ -31,7 +31,7 @@ PROJECT_NAME = HTMLPurifier
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 4.8.0
PROJECT_NUMBER = 4.18.0
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

38
INSTALL
View File

@@ -15,7 +15,7 @@ with these contents.
---------------------------------------------------------------------------
1. Compatibility
HTML Purifier is PHP 5 and PHP 7, and is actively tested from PHP 5.0.5
HTML Purifier is PHP 5 and PHP 7, and is actively tested from PHP 5.3
and up. It has no core dependencies with other libraries.
These optional extensions can enhance the capabilities of HTML Purifier:
@@ -99,32 +99,7 @@ Autoload compatibility
HTML Purifier attempts to be as smart as possible when registering an
autoloader, but there are some cases where you will need to change
your own code to accomodate HTML Purifier. These are those cases:
PHP VERSION IS LESS THAN 5.1.2, AND YOU'VE DEFINED __autoload
Because spl_autoload_register() doesn't exist in early versions
of PHP 5, HTML Purifier has no way of adding itself to the autoload
stack. Modify your __autoload function to test
HTMLPurifier_Bootstrap::autoload($class)
For example, suppose your autoload function looks like this:
function __autoload($class) {
require str_replace('_', '/', $class) . '.php';
return true;
}
A modified version with HTML Purifier would look like this:
function __autoload($class) {
if (HTMLPurifier_Bootstrap::autoload($class)) return true;
require str_replace('_', '/', $class) . '.php';
return true;
}
Note that there *is* some custom behavior in our autoloader; the
original autoloader in our example would work for 99% of the time,
but would fail when including language files.
your own code to accommodate HTML Purifier. These are those cases:
AN __autoload FUNCTION IS DECLARED AFTER OUR AUTOLOADER IS REGISTERED
spl_autoload_register() has the curious behavior of disabling
@@ -138,11 +113,6 @@ Autoload compatibility
spl_autoload_register('__autoload')
Users should also be on guard if they use a version of PHP previous
to 5.1.2 without an autoloader--HTML Purifier will define __autoload()
for you, which can collide with an autoloader that was added by *you*
later.
For better performance
----------------------
@@ -204,9 +174,7 @@ For advanced users
HTMLPurifier.autoload.php
Registers our autoload handler HTMLPurifier_Bootstrap::autoload($class).
You can do these operations by yourself--in fact, you must modify your own
autoload handler if you are using a version of PHP earlier than PHP 5.1.2
(See "Autoload compatibility" above).
You can do these operations by yourself, if you like.
---------------------------------------------------------------------------

View File

@@ -11,7 +11,7 @@ pied de page, mais je recommande de lire le document.
1. Compatibilité
HTML Purifier fonctionne avec PHP 5. PHP 5.0.5 est la dernière version testée.
HTML Purifier fonctionne avec PHP 5. PHP 5.3 est la dernière version testée.
Il ne dépend pas d'autres librairies.
Les extensions optionnelles sont iconv (généralement déjà installée) et tidy

204
NEWS
View File

@@ -1,3 +1,46 @@
# [4.18.0](https://github.com/ezyang/htmlpurifier/compare/v4.17.0...v4.18.0) (2024-11-01)
### Bug Fixes
* Adjust Core.AllowHostnameUnderscore to consider that "_" is defined as Unreserved Characters in RFC 3986 ([#406](https://github.com/ezyang/htmlpurifier/issues/406)) ([d9fbef8](https://github.com/ezyang/htmlpurifier/commit/d9fbef8e27f6a0848a8987a8534351de98eb0fa1))
* Avoid a deprecated error when the attribute name is numeric and DirectLex is used ([#412](https://github.com/ezyang/htmlpurifier/issues/412)) ([f0fbf51](https://github.com/ezyang/htmlpurifier/commit/f0fbf510981b27fc03168efdb17d6bff48f521af))
* checking that node has property name ([#399](https://github.com/ezyang/htmlpurifier/issues/399)) ([9ca5a36](https://github.com/ezyang/htmlpurifier/commit/9ca5a3687bd2e6e42ed9d5199b2cfb1dbd6dbdc2))
* Ignore conditional comments ([#401](https://github.com/ezyang/htmlpurifier/issues/401)) ([4828fdf](https://github.com/ezyang/htmlpurifier/commit/4828fdf45a93eeeacfcbcc855f96f9a7e6b4ed44))
* Support PHP 8.4 ([#396](https://github.com/ezyang/htmlpurifier/issues/396)) ([92da247](https://github.com/ezyang/htmlpurifier/commit/92da2473ffbb3ed5e894560d4166b1ca8032aeb3))
* undefined array key warning ([#419](https://github.com/ezyang/htmlpurifier/issues/419)) ([01be377](https://github.com/ezyang/htmlpurifier/commit/01be377f93654fad4d3fbc8c81779f14316eaecf))
### Features
* Add allowfullscreen attr for iframe ([#411](https://github.com/ezyang/htmlpurifier/issues/411)) ([70754a2](https://github.com/ezyang/htmlpurifier/commit/70754a253342f67a67425cfa81029db3a5c1bd28))
* add directive for removing blank nodes ([#404](https://github.com/ezyang/htmlpurifier/issues/404)) ([c9d60c9](https://github.com/ezyang/htmlpurifier/commit/c9d60c96d799c02bc357c88a49f422034b6914fd))
* Add support for CSS aspect-ratio ([#408](https://github.com/ezyang/htmlpurifier/issues/408)) ([93bee73](https://github.com/ezyang/htmlpurifier/commit/93bee733497a098b65daf5910f1c435d347860a4))
* Allow universal CSS values for all properties ([#410](https://github.com/ezyang/htmlpurifier/issues/410)) ([9723267](https://github.com/ezyang/htmlpurifier/commit/972326785d201b81e1095bc296b99bbcfa8c7fd4))
# [4.17.0](https://github.com/ezyang/htmlpurifier/compare/v4.16.0...v4.17.0) (2023-11-17)
### Bug Fixes
* CSSTidy ImportantComments not handled properly ([#359](https://github.com/ezyang/htmlpurifier/issues/359)) ([78a9b4d](https://github.com/ezyang/htmlpurifier/commit/78a9b4d0dae8bce9a70e4e7e551bf51e9a23706d))
* fix CI ([#361](https://github.com/ezyang/htmlpurifier/issues/361)) ([9ec687c](https://github.com/ezyang/htmlpurifier/commit/9ec687c904a1fe66a5395d22c50f7043e045d1d3))
* Invalid scheme check in Attr.TargetBlank ([#363](https://github.com/ezyang/htmlpurifier/issues/363)) ([0176ef4](https://github.com/ezyang/htmlpurifier/commit/0176ef4bb6f57103fdcb60a802603e60e81ee93e))
* semantic release ([#339](https://github.com/ezyang/htmlpurifier/issues/339)) ([d82f3d9](https://github.com/ezyang/htmlpurifier/commit/d82f3d996a0d9b0f23364946d9a14408c1ad72c5))
* semantic release ([#341](https://github.com/ezyang/htmlpurifier/issues/341)) ([e55fead](https://github.com/ezyang/htmlpurifier/commit/e55fead09f39430d30f48438f06e7bc2326efc94)), closes [#339](https://github.com/ezyang/htmlpurifier/issues/339)
* Support for locales using decimal separators other than . (dot) ([#372](https://github.com/ezyang/htmlpurifier/issues/372)) ([43f49ac](https://github.com/ezyang/htmlpurifier/commit/43f49ac9a51b81dfd07d3bc8dcfc5ec5637a5e3b))
### Features
* Add support for all text-decoration properties ([#360](https://github.com/ezyang/htmlpurifier/issues/360)) ([2d775c0](https://github.com/ezyang/htmlpurifier/commit/2d775c01874e2f676ba1a2d9fe69b47c2a823061))
* Allows commas to be included in tel URI ([#389](https://github.com/ezyang/htmlpurifier/issues/389)) ([ec92490](https://github.com/ezyang/htmlpurifier/commit/ec924901392f088d334622f806b9449b17b75d7b)), closes [#388](https://github.com/ezyang/htmlpurifier/issues/388)
### Reverts
* Revert "fix: semantic release (#339)" (#340) ([3e83215](https://github.com/ezyang/htmlpurifier/commit/3e832152a6173f880c6495a3ab2b0e5235e253a6)), closes [#339](https://github.com/ezyang/htmlpurifier/issues/339) [#340](https://github.com/ezyang/htmlpurifier/issues/340)
NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@@ -9,6 +52,151 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
. Internal change
==========================
4.15.0, released 2022-09-18
! PHP 8.1 and 8.2 support, esp. fixes for deprecation warnings. A joint effort
by David Rans, Tim Düsterhus, Kieran and John Flatness.
! Allow contenteditable="false" (#336), contributed by Kieran.
- Replace PHP 8.1 deprecated utf8_ functions with mbstring (#326),
contributed by John Flatness.
- Enhanced composer suggestions with extensions (#317), contributed by
func0der.
4.14.0, released 2021-12-24
! Add "background-size" support (#289), contributed by Václav Smítal
! Transform deprecated width attribute when tidying HTML, contributed by
Kieran.
- PHP 8 support, contributed by Maksims Sļotovs.
- Improved PHP 7.3 compatibility, contributed by kishor.
- Avoid spurious magic quotes notice in PHP 7.4. Thanks
Jasper Zonneveld for the fix.
- Do not remove thead from table even if there are no tbody/tr (#264).
Thanks Marcus Artner for the fix.
- Fix "Parameter must be an array or an object that implements
Countable" (#285)". Thanks Kieran for this fix.
. Fix unnecessary reference assignment, handling behavior change from
PHP5 and PHP7. Thanks Arkadiusz Biczewski for the fix.
4.13.0, released 2020-06-28
! Add %HTML.Forms directive, which lets you accept forms in user
HTML without requiring full %HTML.Trusted. Note that forms can
be (trivially) used to setup phishing; e.g., an attacker can
use CSS absolute positioning to overlay a form on top of a login
element, so please be sure to use this with care! Fixes #213.
Thanks Mateusz Turcza for contributing this feature.
! tr@bgcolor attribute is now supported. Thanks Kieran Brahney
for this enhancement.
- Further improvements to PHP 7.4 support, contributed by Witold
Wasiczko and Eloy Lafuente.
- Fix PSR-0 compatibility. Thanks Jordi Boggiano for contributing
part of this fix.
- Fix bug with purifyArray where it doesn't work on empty arrays.
Thanks Fräntz Miccoli for the fix.
- Reduce amount of maintenance scripts included in distribution
packages. Thanks Sergei Morozov for this patch.
- Remove leading zeros unless if it is only a zero, fixes #239. Thanks
lubomirbartos for this fix.
- Correct type hinting of maybeGet*, fixes #240. Thanks Anders Jenbo
for this fix.
4.12.0, released 2019-10-27
! PHP 7.4 is supported, thank you Witold Wasiczko, Mateuz Turcza and
Edi Modrić
- PHPDocs for HTMLModule::addElement() and Bool attr are fixed (thanks
Mateusz)
4.11.0, released 2019-07-14
# SafeScripting now matches case-sensitively against its whitelist (previously it was
case-insensitive.) Thanks Dimitri Gritsajuk <gritsajuk.dimitri@gmail.com>
for reporting.
! New directive %Core.AllowParseManyTags which allows parsing of many nested tags.
Thanks M. Suzuki <msuzuki1986@gmail.com> for contributing the patch.
! purifyArray now supports multidimensional arrays. Thanks
Sandro Miguel Marques <sandromiguel@sandromiguel.com> for contributing this patch.
! initial and inherit settings available for width, height, and the min-/max-
versions thereof. Thanks Michael Kliewe <info@phpgansta.de> for contributing
this patch.
! More color names are supported. Thanks Daijobou for contributing.
- Compatibility fixes for PHP 7.3, including new CI for PHP 7.3
(thank you Lukas Neumann <lksnmnn@gmail.com>) and removal of
reserved words in our constants (thanks Darko Hrgovic <darko@darkodev.com>
- Compatibility fixes for HHVM. Thanks Mateusz Turcza for contributing
this fix.
- HTML Purifier now never defines __autoload, fixing #196. Thanks
Michael Kliewe for reporting.
- In some situations, Config.php would report an undefined index: class
error; this has been fixed. Thanks DiLong Fa for contributing
this fix.
- We no longer produce <script /> tags; we always explicitly write
out the open and close tag. Thanks Dimitri Gritsajuk
<gritsajuk.dimitri@gmail.com> for contributing this fix.
- Better compatibility when IDNA constants are not present. Thanks
Mateusz Turcza <xemlock@gmail.com> for contributing this fix.
4.10.0, released 2018-02-22
# PHP 5.3 is no longer officially supported by HTML Purifier
(we did not specifically break support, but we are no longer
testing on PHP 5.3)
! Relative CSS length units are now supported
- A few PHP 7.2 compatibility fixes, thanks John Flatness
<john@zerocrates.org>
- Improve portability with old versions of libxml which don't
support accessing the data of a node
- IDNA2008 is now used for converting domains to ASCII, fixing
some rather strange bugs with international domains
- Fix race condition resulting in E_WARNING when creating
directories with Serializer
4.9.3, released 2017-06-02
- Workaround PHP 7.1 infinite loop when opcode cache is enabled.
Thanks @Xiphin (#134, #135)
- Don't use autoloader when testing for DOMDocument. Hypothetically,
this could cause your install to start using DirectLex if you had
previously been monkeypatching in a custom, autoloaded implementation
of DOMDocument. Don't do that. Thanks @Izumi-kun (#130)
4.9.2, released 2017-03-12
- Fixes PHP 5.3 compatibility
- Fix breakage when decoding decimal entities. Thanks @rybakit (#129)
4.9.1, released 2017-03-08
! %URI.DefaultScheme can now be set to null, in which case
all relative paths are removed.
! New CSS properties: min-width, max-width, min-height, max-height (#94)
! Transparency (rgba) and hsl/hsla supported where color CSS is present.
Thanks @fxbt for contributing the patch. (#118)
- When idn_to_ascii is defined, we might accept malformed
hostnames. Apply validation to the result in such cases.
- Close directory when done in Serializer DefinitionCache (#100)
- Deleted some asserts to avoid linters from choking (#97)
- Rework Serializer cache behavior to avoid chmod'ing if possible (#32)
- Embedded semicolons in strings in CSS are now handled correctly!
- We accidentally dropped certain Unicode characters if there was
one or more invalid characters. This has been fixed, thanks
to mpyw <ryosuke_i_628@yahoo.co.jp>
- Fix for "Don't truncate upon encountering </div> when using DOMLex"
caused a regression with HTML 4.01 Strict parsing with libxml 2.9.1
(and maybe later versions, but known OK with libxml 2.9.4). The
fix is to go about handling truncation a bit more cleverly so that
we can wrap with divs (sidestepping the bug) but slurping out the
rest of the text in case it ran off the end. (#78)
- Fix PREG_BACKTRACK_LIMIT_ERROR in HTMLPurifier_Filter_ExtractStyle.
Thanks @breathbath for contributing the report and fix (#120)
- Fix entity decoding algorithm to be more conservative about
decoding entities that are missing trailing semicolon.
To get old behavior, set %Core.LegacyEntityDecoder to true.
(#119)
- Workaround libxml bug when HTML tags are embedded inside
script tags. To disable workaround set %Core.AggressivelyRemoveScript
to false. (#83)
# By default, when a link has a target attribute associated
with it, we now also add rel="noopener" in order to
prevent the new window from being able to overwrite
the original frame. To disable this protection,
set %HTML.TargetNoopener to FALSE.
4.9.0 was cut on Git but never properly released; when we did the
real release we decided to skip this version number.
4.8.0, released 2016-07-16
# By default, when a link has a target attribute associated
with it, we now also add rel="noreferrer" in order to
@@ -294,7 +482,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
3.3.0, released 2009-02-16
! Implement CSS property 'overflow' when %CSS.AllowTricky is true.
! Implement generic property list classess
! Implement generic property list classes
- Fix bug with testEncodingSupportsASCII() algorithm when iconv() implementation
does not do the "right thing" with characters not supported in the output
set.
@@ -334,7 +522,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
! %Core.AggressivelyFixLt is on by default. This causes more sensible
processing of left angled brackets in smileys and other whatnot.
! Test scripts now have a 'type' parameter, which lets you say 'htmlpurifier',
'phpt', 'vtest', etc. in order to only execute those tests. This supercedes
'phpt', 'vtest', etc. in order to only execute those tests. This supersedes
the --only-phpt parameter, although for backwards-compatibility the flag
will still work.
! AutoParagraph auto-formatter will now preserve double-newlines upon output.
@@ -385,7 +573,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
. Added --quick option to multitest.php, which tests only the most recent
release for each series.
. Added --distro option to multitest.php, which accepts either 'normal' or
'standalone'. This supercedes --exclude-normal and --exclude-standalone
'standalone'. This supersedes --exclude-normal and --exclude-standalone
3.1.1, released 2008-06-19
# %URI.Munge now, by default, does not munge resources (for example, <img src="">)
@@ -535,7 +723,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
# HTMLPurifier->addFilter is deprecated; built-in filters can now be
enabled using %Filter.$filter_name or by setting your own filters using
%Filter.Custom
# Directive-level safety properties superceded in favor of module-level
# Directive-level safety properties superseded in favor of module-level
safety. Internal method HTMLModule->addElement() has changed, although
the externally visible HTMLDefinition->addElement has *not* changed.
! Extra utility classes for testing and non-library operations can
@@ -581,7 +769,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
. A couple of new historical maintenance scripts were added.
. HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php split into two files
. tests/index.php can now be run from any directory.
. HTMLPurifier_Token subclasses split into seperate files
. HTMLPurifier_Token subclasses split into separate files
. HTMLPURIFIER_PREFIX now is defined in Bootstrap.php, NOT HTMLPurifier.php
. HTMLPURIFIER_PREFIX can now be defined outside of HTML Purifier
. New --php=php flag added, allows PHP executable to be specified (command
@@ -647,7 +835,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
- Fix warning emitted when a non-supported URI scheme is passed to the
MakeAbsolute URIFilter, thanks NykO18 (again)
- Further refine AutoParagraph injector. Behavior inside of elements
allowing paragraph tags clarified: only inline content delimeted by
allowing paragraph tags clarified: only inline content delimited by
double newlines (not block elements) are paragraphed.
- Buggy treatment of end tags of elements that have required attributes
fixed (does not manifest on default tag-set)
@@ -693,7 +881,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
! CSS property border-spacing implemented
- Fix non-visible parsing error in DirectLex with empty tags that have
slashes inside attribute values.
- Fix typo in CSS definition: border-collapse:seperate; was incorrectly
- Fix typo in CSS definition: border-collapse:separate; was incorrectly
accepted as valid CSS. Usually non-visible, because this styling is the
default for tables in most browsers. Thanks Brett Zamir for pointing
this out.
@@ -744,7 +932,7 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
. HTMLPurifier_Config->getSerial() implemented, this is extremely useful
for output cache invalidation
. ConfigForm printer now can retrieve CSS and JS files as strings, in
case HTML Purifier's directory is not publically accessible
case HTML Purifier's directory is not publicly accessible
. Introduce new text/itext configuration directive values: these represent
longer strings that would be more appropriately edited with a textarea
. Allow newlines to act as separators for lists, hashes, lookups and

View File

@@ -1,8 +1,8 @@
HTML Purifier
HTML Purifier [![Build Status](https://github.com/ezyang/htmlpurifier/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/ezyang/htmlpurifier/actions/workflows/ci.yml)
=============
HTML Purifier is an HTML filtering solution that uses a unique combination
of robust whitelists and agressive parsing to ensure that not only are
of robust whitelists and aggressive parsing to ensure that not only are
XSS attacks thwarted, but the resulting HTML is standards compliant.
HTML Purifier is oriented towards richly formatted documents from
@@ -26,4 +26,4 @@ Package available on [Composer](https://packagist.org/packages/ezyang/htmlpurifi
If you're using Composer to manage dependencies, you can use
$ composer require "ezyang/htmlpurifier": "dev-master"
$ composer require ezyang/htmlpurifier

4
TODO
View File

@@ -41,7 +41,7 @@ FUTURE VERSIONS
- Config: Add examples to everything (make built-in which also automatically
gives output)
- Add "register" field to config schemas to eliminate dependence on
naming conventions (try to remember why we ultimately decided on tihs)
naming conventions (try to remember why we ultimately decided on this)
5.0 release [HTML 5]
# Swap out code to use html5lib tokenizer and tree-builder
@@ -112,7 +112,7 @@ Neat feature related
Also, enable disabling of directionality
? Externalize inline CSS to promote clean HTML, proposed by Sander Tekelenburg
? Remove redundant tags, ex. <u><u>Underlined</u></u>. Implementation notes:
1. Analyzing which tags to remove duplicants
1. Analyzing which tags to remove duplicates
2. Ensure attributes are merged into the parent tag
3. Extend the tag exclusion system to specify whether or not the
contents should be dropped or not (currently, there's code that could do

View File

@@ -1 +1 @@
4.8.0
4.18.0

View File

@@ -1,9 +0,0 @@
HTML Purifier 4.8.0 is a bugfix release, collecting a year
of accumulated bug fixes. In particular, we fixed some minor
bugs and now declare full PHP 7 compatibility. The primary
backwards-incompatible change is that HTML Purifier will now
add rel="noreferrer" to all links with target attributes
(you can disable this with %HTML.TargetNoReferrer.) Other
changes: new configuration options %CSS.AllowDuplicates and
%Attr.ID.HTML5; border-radius is partially supported when
%CSS.AllowProprietary, and tel URIs are supported by default.

View File

@@ -1 +1,7 @@
Deny from all
<IfModule mod_authz_core.c>
Require all denied
</IfModule>
<IfModule !mod_authz_core.c>
Deny from all
</ifModule>

View File

@@ -392,7 +392,7 @@ Women practicing non-martial T'ai Chi in <a href="/wiki/Chinatown_%28Manhattan%2
<li><a href="http://www.scheele.org/lee/tcclinks.html" class="external text" title="http://www.scheele.org/lee/tcclinks.html">Lee Scheele's Links to T'ai Chi Ch'uan Web Sites</a></li>
<li><a href="http://news.bbc.co.uk/1/hi/health/3543907.stm" class="external text" title="http://news.bbc.co.uk/1/hi/health/3543907.stm">BBC article</a></li>
<li><a href="http://www.acupuncturetoday.com/archives2004/jul/07taichi.html" class="external text" title="http://www.acupuncturetoday.com/archives2004/jul/07taichi.html">Tai Chi: Good for the Mind, Good for the Body</a></li>
<li><a href="http://www.taichiunion.com/" class="external text" title="http://www.taichiunion.com/">Tai Chi Chuan Union for Great Britian: The largest collective of independent Tai Chi Chuan Instructors in the British Isles</a></li>
<li><a href="http://www.taichiunion.com/" class="external text" title="http://www.taichiunion.com/">Tai Chi Chuan Union for Great Britain: The largest collective of independent Tai Chi Chuan Instructors in the British Isles</a></li>
</ul>

View File

@@ -4,7 +4,7 @@
"type": "library",
"keywords": ["html"],
"homepage": "http://htmlpurifier.org/",
"license": "LGPL",
"license": "LGPL-2.1-or-later",
"authors": [
{
"name": "Edward Z. Yang",
@@ -13,10 +13,33 @@
}
],
"require": {
"php": ">=5.2"
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
},
"require-dev": {
"cerdic/css-tidy": "^1.7 || ^2.0",
"simpletest/simpletest": "dev-master"
},
"autoload": {
"psr-0": { "HTMLPurifier": "library/" },
"files": ["library/HTMLPurifier.composer.php"]
}
"files": ["library/HTMLPurifier.composer.php"],
"exclude-from-classmap": [
"/library/HTMLPurifier/Language/"
]
},
"suggest": {
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
"ext-bcmath": "Used for unit conversion and imagecrash protection",
"ext-tidy": "Used for pretty-printing HTML"
},
"config": {
"sort-packages": true
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/ezyang/simpletest.git",
"no-api": true
}
]
}

View File

@@ -16,7 +16,7 @@ TODO:
*/
if (version_compare(PHP_VERSION, '5.2', '<')) exit('PHP 5.2+ required.');
error_reporting(E_ALL | E_STRICT);
error_reporting(E_ALL);
// load dual-libraries
require_once dirname(__FILE__) . '/../extras/HTMLPurifierExtras.auto.php';

View File

@@ -5,7 +5,7 @@
<line>162</line>
</file>
<file name="HTMLPurifier/Lexer.php">
<line>85</line>
<line>90</line>
<line>315</line>
</file>
<file name="HTMLPurifier/Lexer/DirectLex.php">
@@ -19,37 +19,37 @@
</directive>
<directive id="CSS.MaxImgLength">
<file name="HTMLPurifier/CSSDefinition.php">
<line>226</line>
<line>253</line>
</file>
</directive>
<directive id="CSS.Proprietary">
<file name="HTMLPurifier/CSSDefinition.php">
<line>319</line>
<line>397</line>
</file>
</directive>
<directive id="CSS.AllowTricky">
<file name="HTMLPurifier/CSSDefinition.php">
<line>323</line>
<line>401</line>
</file>
</directive>
<directive id="CSS.Trusted">
<file name="HTMLPurifier/CSSDefinition.php">
<line>327</line>
<line>405</line>
</file>
</directive>
<directive id="CSS.AllowImportant">
<file name="HTMLPurifier/CSSDefinition.php">
<line>331</line>
<line>409</line>
</file>
</directive>
<directive id="CSS.AllowedProperties">
<file name="HTMLPurifier/CSSDefinition.php">
<line>460</line>
<line>538</line>
</file>
</directive>
<directive id="CSS.ForbiddenProperties">
<file name="HTMLPurifier/CSSDefinition.php">
<line>476</line>
<line>554</line>
</file>
</directive>
<directive id="Cache.DefinitionImpl">
@@ -79,19 +79,19 @@
</directive>
<directive id="Core.Encoding">
<file name="HTMLPurifier/Encoder.php">
<line>374</line>
<line>422</line>
<line>380</line>
<line>428</line>
</file>
</directive>
<directive id="Test.ForceNoIconv">
<file name="HTMLPurifier/Encoder.php">
<line>382</line>
<line>433</line>
<line>388</line>
<line>439</line>
</file>
</directive>
<directive id="Core.EscapeNonASCIICharacters">
<file name="HTMLPurifier/Encoder.php">
<line>423</line>
<line>429</line>
</file>
</directive>
<directive id="Output.CommentScriptContents">
@@ -124,7 +124,7 @@
<line>122</line>
</file>
<file name="HTMLPurifier/Lexer.php">
<line>297</line>
<line>299</line>
</file>
</directive>
<directive id="Output.Newline">
@@ -172,7 +172,14 @@
<line>234</line>
</file>
<file name="HTMLPurifier/Lexer.php">
<line>302</line>
<line>304</line>
<line>342</line>
</file>
<file name="HTMLPurifier/AttrDef/HTML/ContentEditable.php">
<line>8</line>
</file>
<file name="HTMLPurifier/HTMLModule/Iframe.php">
<line>43</line>
</file>
<file name="HTMLPurifier/HTMLModule/Image.php">
<line>37</line>
@@ -232,6 +239,11 @@
<line>276</line>
</file>
</directive>
<directive id="HTML.TargetNoopener">
<file name="HTMLPurifier/HTMLModuleManager.php">
<line>279</line>
</file>
</directive>
<directive id="Attr.IDBlacklist">
<file name="HTMLPurifier/IDAccumulator.php">
<line>27</line>
@@ -244,17 +256,23 @@
</directive>
<directive id="Core.LexerImpl">
<file name="HTMLPurifier/Lexer.php">
<line>80</line>
<line>85</line>
</file>
</directive>
<directive id="Core.MaintainLineNumbers">
<file name="HTMLPurifier/Lexer.php">
<line>84</line>
<line>89</line>
</file>
<file name="HTMLPurifier/Lexer/DirectLex.php">
<line>62</line>
</file>
</directive>
<directive id="Core.LegacyEntityDecoder">
<file name="HTMLPurifier/Lexer.php">
<line>220</line>
<line>326</line>
</file>
</directive>
<directive id="Core.ConvertDocumentToFragment">
<file name="HTMLPurifier/Lexer.php">
<line>313</line>
@@ -262,7 +280,28 @@
</directive>
<directive id="Core.RemoveProcessingInstructions">
<file name="HTMLPurifier/Lexer.php">
<line>334</line>
<line>336</line>
</file>
</directive>
<directive id="Core.HiddenElements">
<file name="HTMLPurifier/Lexer.php">
<line>340</line>
</file>
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
<line>36</line>
</file>
</directive>
<directive id="Core.AggressivelyRemoveScript">
<file name="HTMLPurifier/Lexer.php">
<line>341</line>
</file>
</directive>
<directive id="Core.RemoveScriptContents">
<file name="HTMLPurifier/Lexer.php">
<line>342</line>
</file>
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
<line>35</line>
</file>
</directive>
<directive id="URI.">
@@ -313,7 +352,7 @@
</directive>
<directive id="Core.ColorKeywords">
<file name="HTMLPurifier/AttrDef/CSS/Color.php">
<line>19</line>
<line>29</line>
</file>
<file name="HTMLPurifier/AttrDef/HTML/Color.php">
<line>19</line>
@@ -321,7 +360,7 @@
</directive>
<directive id="CSS.AllowedFonts">
<file name="HTMLPurifier/AttrDef/CSS/FontFamily.php">
<line>64</line>
<line>62</line>
</file>
</directive>
<directive id="Attr.AllowedClasses">
@@ -372,12 +411,12 @@
</directive>
<directive id="Core.AllowHostnameUnderscore">
<file name="HTMLPurifier/AttrDef/URI/Host.php">
<line>77</line>
<line>71</line>
</file>
</directive>
<directive id="Core.EnableIDNA">
<file name="HTMLPurifier/AttrDef/URI/Host.php">
<line>105</line>
<line>103</line>
</file>
</directive>
<directive id="Attr.DefaultTextDir">
@@ -418,33 +457,38 @@
</directive>
<directive id="HTML.FlashAllowFullScreen">
<file name="HTMLPurifier/AttrTransform/SafeParam.php">
<line>53</line>
<line>58</line>
</file>
</directive>
<directive id="Cache.SerializerPath">
<file name="HTMLPurifier/DefinitionCache/Serializer.php">
<line>183</line>
<line>185</line>
</file>
</directive>
<directive id="Cache.SerializerPermissions">
<file name="HTMLPurifier/DefinitionCache/Serializer.php">
<line>200</line>
<line>219</line>
<line>202</line>
<line>218</line>
</file>
</directive>
<directive id="Filter.ExtractStyleBlocks.TidyImpl">
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
<line>94</line>
<line>106</line>
</file>
</directive>
<directive id="Filter.ExtractStyleBlocks.Scope">
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
<line>122</line>
<line>137</line>
</file>
</directive>
<directive id="Filter.ExtractStyleBlocks.Escaping">
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
<line>327</line>
<line>351</line>
</file>
</directive>
<directive id="HTML.Forms">
<file name="HTMLPurifier/HTMLModule/Forms.php">
<line>31</line>
</file>
</directive>
<directive id="HTML.SafeIframe">
@@ -506,6 +550,16 @@
<line>54</line>
</file>
</directive>
<directive id="Core.AllowParseManyTags">
<file name="HTMLPurifier/Lexer/DOMLex.php">
<line>72</line>
</file>
</directive>
<directive id="Core.RemoveBlanks">
<file name="HTMLPurifier/Lexer/DOMLex.php">
<line>75</line>
</file>
</directive>
<directive id="Core.DirectLexLineNumberSyncInterval">
<file name="HTMLPurifier/Lexer/DirectLex.php">
<line>84</line>
@@ -534,16 +588,6 @@
<line>32</line>
</file>
</directive>
<directive id="Core.RemoveScriptContents">
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
<line>35</line>
</file>
</directive>
<directive id="Core.HiddenElements">
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
<line>36</line>
</file>
</directive>
<directive id="URI.HostBlacklist">
<file name="HTMLPurifier/URIFilter/HostBlacklist.php">
<line>25</line>
@@ -564,4 +608,9 @@
<line>35</line>
</file>
</directive>
<directive id="URI.SafeIframeHosts">
<file name="HTMLPurifier/URIFilter/SafeIframe.php">
<line>67</line>
</file>
</directive>
</usage>

9
docker-compose.yaml Normal file
View File

@@ -0,0 +1,9 @@
services:
htmlpurifier:
build:
context: "."
dockerfile: Dockerfile
container_name: 'htmlpurifier'
tty: true
volumes:
- .:/opt/htmlpurifier

View File

@@ -49,7 +49,7 @@ the properties:
AllowedFrameTargets -> heavily <a> specific, but also used by <area>
and <form>. Transitional DTD %FrameTarget, not present in strict,
HTML5 calls them "browsing contexts"
Default*Image* -> as a default parameter, is almost entirely exlcusive
Default*Image* -> as a default parameter, is almost entirely exclusive
to <img>
EnableID -> global attribute
Name.UseCDATA -> heavily <a> specific, but has heavy other usage by
@@ -75,6 +75,7 @@ Core is the potpourri of directives, mostly regarding some minor behavioral
tweaks for HTML handling abilities.
AggressivelyFixLt
AllowParseManyTags
ConvertDocumentToFragment
DirectLexLineNumberSyncInterval
LexerImpl

View File

@@ -228,7 +228,7 @@ Test.Example</pre>
</tr>
<tr>
<td>mixed</td>
<td>new stdclass</td>
<td>new stdClass</td>
<td>Any PHP variable is fine</td>
</tr>
</tbody>

View File

@@ -122,7 +122,7 @@ thead th {text-align:left;padding:0.1em;background-color:#EEE;}
<tbody>
<tr><th colspan="2">Table</th></tr>
<tr class="impl-yes"><td>border-collapse</td><td>ENUM(collapse, seperate)</td></tr>
<tr class="impl-yes"><td>border-collapse</td><td>ENUM(collapse, separate)</td></tr>
<tr class="impl-yes"><td>border-space</td><td>MULTIPLE</td></tr>
<tr class="impl-yes"><td>caption-side</td><td>ENUM(top, bottom)</td></tr>
<tr class="feature"><td>empty-cells</td><td>ENUM(show, hide), No IE support makes this useless,

View File

@@ -163,7 +163,7 @@ smoketest</a>.</p>
<p>So you want HTML Purifier to clean up your HTML, but you're not
so happy about the br@clear implementation. That's perfectly fine!
HTML Purifier will make accomodations:</p>
HTML Purifier will make accommodations:</p>
<pre>$config-&gt;set('HTML.Doctype', 'XHTML 1.0 Transitional');
$config-&gt;set('HTML.TidyLevel', 'heavy'); // all changes, minus...

View File

@@ -60,7 +60,7 @@ These are special use tags, they should be enabled on a blanket basis.
Lists - dd, dl, dt, li, ol, ul ~ menu, dir
Tables - caption, table, td, th, tr / col, colgroup, tbody, tfoot, thead
Forms - fieldset, form, input, lable, legend, optgroup, option, select, textarea
Forms - fieldset, form, input, label, legend, optgroup, option, select, textarea
XSS - noscript, object, script ~ applet
Meta - base, basefont, body, head, html, link, meta, style, title
Frames - frame, frameset, iframe
@@ -91,7 +91,7 @@ attribute and put URI filtering higher up on the priority list.
== Attribute Risk Analysis ==
We actually have a suprisingly small assortment of allowed attributes (the
We actually have a surprisingly small assortment of allowed attributes (the
rest are deprecated in strict, and thus we opted not to allow them, even
though our output is XHTML Transitional by default.)

View File

@@ -70,7 +70,7 @@ Backfills/Data integrity:
Type systems:
- Flags: ReadOnly, Permanent, DontEnum
- Typed properties isn't that useful [It's also Not-PHP]
- Seperate meta-list of directive properties IS useful
- Separate meta-list of directive properties IS useful
- Duck typing is useful for systems designed fully around properties pattern
Trade-off:

View File

@@ -136,7 +136,7 @@ class FSTools
/**
* Recursively globs a directory.
*/
public function globr($dir, $pattern, $flags = NULL)
public function globr($dir, $pattern, $flags = 0)
{
$files = $this->glob("$dir/$pattern", $flags);
if ($files === false) $files = array();

View File

@@ -0,0 +1,15 @@
<?php
/**
* @file
* Legacy autoloader for systems lacking spl_autoload_register
*
* Must be separate to prevent deprecation warning on PHP 7.2
*/
function __autoload($class)
{
return HTMLPurifierExtras::autoload($class);
}
// vim: et sw=4 sts=4

View File

@@ -17,10 +17,7 @@ if (function_exists('spl_autoload_register')) {
spl_autoload_register('__autoload');
}
} elseif (!function_exists('__autoload')) {
function __autoload($class)
{
return HTMLPurifierExtras::autoload($class);
}
require dirname(__FILE__) . '/HTMLPurifierExtras.autoload-legacy.php';
}
// vim: et sw=4 sts=4

View File

@@ -0,0 +1,14 @@
<?php
/**
* @file
* Legacy autoloader for systems lacking spl_autoload_register
*
*/
spl_autoload_register(function($class)
{
return HTMLPurifier_Bootstrap::autoload($class);
});
// vim: et sw=4 sts=4

View File

@@ -14,12 +14,10 @@ if (function_exists('spl_autoload_register') && function_exists('spl_autoload_un
spl_autoload_register('__autoload');
}
} elseif (!function_exists('__autoload')) {
function __autoload($class)
{
return HTMLPurifier_Bootstrap::autoload($class);
}
require dirname(__FILE__) . '/HTMLPurifier.autoload-legacy.php';
}
// phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.zend_ze1_compatibility_modeRemoved
if (ini_get('zend.ze1_compatibility_mode')) {
trigger_error("HTML Purifier is not compatible with zend.ze1_compatibility_mode; please turn it off", E_USER_ERROR);
}

View File

@@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.8.0
* @version 4.18.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
@@ -101,12 +101,14 @@ require 'HTMLPurifier/AttrDef/CSS/Length.php';
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
require 'HTMLPurifier/AttrDef/CSS/Percentage.php';
require 'HTMLPurifier/AttrDef/CSS/Ratio.php';
require 'HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require 'HTMLPurifier/AttrDef/CSS/URI.php';
require 'HTMLPurifier/AttrDef/HTML/Bool.php';
require 'HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require 'HTMLPurifier/AttrDef/HTML/Class.php';
require 'HTMLPurifier/AttrDef/HTML/Color.php';
require 'HTMLPurifier/AttrDef/HTML/ContentEditable.php';
require 'HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require 'HTMLPurifier/AttrDef/HTML/ID.php';
require 'HTMLPurifier/AttrDef/HTML/Pixels.php';
@@ -137,6 +139,7 @@ require 'HTMLPurifier/AttrTransform/SafeObject.php';
require 'HTMLPurifier/AttrTransform/SafeParam.php';
require 'HTMLPurifier/AttrTransform/ScriptRequired.php';
require 'HTMLPurifier/AttrTransform/TargetBlank.php';
require 'HTMLPurifier/AttrTransform/TargetNoopener.php';
require 'HTMLPurifier/AttrTransform/TargetNoreferrer.php';
require 'HTMLPurifier/AttrTransform/Textarea.php';
require 'HTMLPurifier/ChildDef/Chameleon.php';
@@ -176,6 +179,7 @@ require 'HTMLPurifier/HTMLModule/StyleAttribute.php';
require 'HTMLPurifier/HTMLModule/Tables.php';
require 'HTMLPurifier/HTMLModule/Target.php';
require 'HTMLPurifier/HTMLModule/TargetBlank.php';
require 'HTMLPurifier/HTMLModule/TargetNoopener.php';
require 'HTMLPurifier/HTMLModule/TargetNoreferrer.php';
require 'HTMLPurifier/HTMLModule/Text.php';
require 'HTMLPurifier/HTMLModule/Tidy.php';

View File

@@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.8.0 - Standards Compliant HTML Filtering
HTML Purifier 4.18.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier.
* @type string
*/
public $version = '4.8.0';
public $version = '4.18.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.8.0';
const VERSION = '4.18.0';
/**
* Global configuration object.
@@ -240,12 +240,17 @@ class HTMLPurifier
public function purifyArray($array_of_html, $config = null)
{
$context_array = array();
foreach ($array_of_html as $key => $html) {
$array_of_html[$key] = $this->purify($html, $config);
$array = array();
foreach($array_of_html as $key=>$value){
if (is_array($value)) {
$array[$key] = $this->purifyArray($value, $config);
} else {
$array[$key] = $this->purify($value, $config);
}
$context_array[$key] = $this->context;
}
$this->context = $context_array;
return $array_of_html;
return $array;
}
/**

View File

@@ -95,12 +95,14 @@ require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Length.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/ListStyle.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Multiple.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Percentage.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/Ratio.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/TextDecoration.php';
require_once $__dir . '/HTMLPurifier/AttrDef/CSS/URI.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Bool.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Nmtokens.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Class.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Color.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ContentEditable.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/FrameTarget.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/ID.php';
require_once $__dir . '/HTMLPurifier/AttrDef/HTML/Pixels.php';
@@ -131,6 +133,7 @@ require_once $__dir . '/HTMLPurifier/AttrTransform/SafeObject.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/SafeParam.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/ScriptRequired.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/TargetBlank.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/TargetNoopener.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/TargetNoreferrer.php';
require_once $__dir . '/HTMLPurifier/AttrTransform/Textarea.php';
require_once $__dir . '/HTMLPurifier/ChildDef/Chameleon.php';
@@ -170,6 +173,7 @@ require_once $__dir . '/HTMLPurifier/HTMLModule/StyleAttribute.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tables.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Target.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetBlank.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetNoopener.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/TargetNoreferrer.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Text.php';
require_once $__dir . '/HTMLPurifier/HTMLModule/Tidy.php';

View File

@@ -19,8 +19,8 @@ class HTMLPurifier_Arborize
if ($token instanceof HTMLPurifier_Token_End) {
$token->start = null; // [MUT]
$r = array_pop($stack);
assert($r->name === $token->name);
assert(empty($token->attr));
//assert($r->name === $token->name);
//assert(empty($token->attr));
$r->endCol = $token->col;
$r->endLine = $token->line;
$r->endArmor = $token->armor;
@@ -32,7 +32,7 @@ class HTMLPurifier_Arborize
$stack[] = $node;
}
}
assert(count($stack) == 1);
//assert(count($stack) == 1);
return $stack[0];
}

View File

@@ -86,7 +86,13 @@ abstract class HTMLPurifier_AttrDef
*/
protected function mungeRgb($string)
{
return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string);
$p = '\s*(\d+(\.\d+)?([%]?))\s*';
if (preg_match('/(rgba|hsla)\(/', $string)) {
return preg_replace('/(rgba|hsla)\('.$p.','.$p.','.$p.','.$p.'\)/', '\1(\2,\5,\8,\11)', $string);
}
return preg_replace('/(rgb|hsl)\('.$p.','.$p.','.$p.'\)/', '\1(\2,\5,\8)', $string);
}
/**

View File

@@ -27,13 +27,45 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
$definition = $config->getCSSDefinition();
$allow_duplicates = $config->get("CSS.AllowDuplicates");
// we're going to break the spec and explode by semicolons.
// This is because semicolon rarely appears in escaped form
// Doing this is generally flaky but fast
// IT MIGHT APPEAR IN URIs, see HTMLPurifier_AttrDef_CSSURI
// for details
$universal_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'initial',
'inherit',
'unset',
)
);
// According to the CSS2.1 spec, the places where a
// non-delimiting semicolon can appear are in strings
// escape sequences. So here is some dumb hack to
// handle quotes.
$len = strlen($css);
$accum = "";
$declarations = array();
$quoted = false;
for ($i = 0; $i < $len; $i++) {
$c = strcspn($css, ";'\"", $i);
$accum .= substr($css, $i, $c);
$i += $c;
if ($i == $len) break;
$d = $css[$i];
if ($quoted) {
$accum .= $d;
if ($d == $quoted) {
$quoted = false;
}
} else {
if ($d == ";") {
$declarations[] = $accum;
$accum = "";
} else {
$accum .= $d;
$quoted = $d;
}
}
}
if ($accum != "") $declarations[] = $accum;
$declarations = explode(';', $css);
$propvalues = array();
$new_declarations = '';
@@ -71,16 +103,13 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
if (!$ok) {
continue;
}
// inefficient call, since the validator will do this again
if (strtolower(trim($value)) !== 'inherit') {
// inherit works for everything (but only on the base property)
$result = $universal_attrdef->validate($value, $config, $context);
if ($result === false) {
$result = $definition->info[$property]->validate(
$value,
$config,
$context
);
} else {
$result = 'inherit';
}
if ($result === false) {
continue;

View File

@@ -25,6 +25,7 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
$this->info['background-repeat'] = $def->info['background-repeat'];
$this->info['background-attachment'] = $def->info['background-attachment'];
$this->info['background-position'] = $def->info['background-position'];
$this->info['background-size'] = $def->info['background-size'];
}
/**
@@ -53,6 +54,7 @@ class HTMLPurifier_AttrDef_CSS_Background extends HTMLPurifier_AttrDef
$caught['repeat'] = false;
$caught['attachment'] = false;
$caught['position'] = false;
$caught['size'] = false;
$i = 0; // number of catches

View File

@@ -6,6 +6,16 @@
class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
{
/**
* @type HTMLPurifier_AttrDef_CSS_AlphaValue
*/
protected $alpha;
public function __construct()
{
$this->alpha = new HTMLPurifier_AttrDef_CSS_AlphaValue();
}
/**
* @param string $color
* @param HTMLPurifier_Config $config
@@ -29,59 +39,104 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
return $colors[$lower];
}
if (strpos($color, 'rgb(') !== false) {
// rgb literal handling
if (preg_match('#(rgb|rgba|hsl|hsla)\(#', $color, $matches) === 1) {
$length = strlen($color);
if (strpos($color, ')') !== $length - 1) {
return false;
}
$triad = substr($color, 4, $length - 4 - 1);
$parts = explode(',', $triad);
if (count($parts) !== 3) {
// get used function : rgb, rgba, hsl or hsla
$function = $matches[1];
$parameters_size = 3;
$alpha_channel = false;
if (substr($function, -1) === 'a') {
$parameters_size = 4;
$alpha_channel = true;
}
/*
* Allowed types for values :
* parameter_position => [type => max_value]
*/
$allowed_types = array(
1 => array('percentage' => 100, 'integer' => 255),
2 => array('percentage' => 100, 'integer' => 255),
3 => array('percentage' => 100, 'integer' => 255),
);
$allow_different_types = false;
if (strpos($function, 'hsl') !== false) {
$allowed_types = array(
1 => array('integer' => 360),
2 => array('percentage' => 100),
3 => array('percentage' => 100),
);
$allow_different_types = true;
}
$values = trim(str_replace($function, '', $color), ' ()');
$parts = explode(',', $values);
if (count($parts) !== $parameters_size) {
return false;
}
$type = false; // to ensure that they're all the same type
$type = false;
$new_parts = array();
$i = 0;
foreach ($parts as $part) {
$i++;
$part = trim($part);
if ($part === '') {
return false;
}
$length = strlen($part);
if ($part[$length - 1] === '%') {
// handle percents
if (!$type) {
$type = 'percentage';
} elseif ($type !== 'percentage') {
// different check for alpha channel
if ($alpha_channel === true && $i === count($parts)) {
$result = $this->alpha->validate($part, $config, $context);
if ($result === false) {
return false;
}
$num = (float)substr($part, 0, $length - 1);
if ($num < 0) {
$num = 0;
}
if ($num > 100) {
$num = 100;
}
$new_parts[] = "$num%";
$new_parts[] = (string)$result;
continue;
}
if (substr($part, -1) === '%') {
$current_type = 'percentage';
} else {
// handle integers
if (!$type) {
$type = 'integer';
} elseif ($type !== 'integer') {
return false;
}
$num = (int)$part;
if ($num < 0) {
$num = 0;
}
if ($num > 255) {
$num = 255;
}
$new_parts[] = (string)$num;
$current_type = 'integer';
}
if (!array_key_exists($current_type, $allowed_types[$i])) {
return false;
}
if (!$type) {
$type = $current_type;
}
if ($allow_different_types === false && $type != $current_type) {
return false;
}
$max_value = $allowed_types[$i][$current_type];
if ($current_type == 'integer') {
// Return value between range 0 -> $max_value
$new_parts[] = (int)max(min($part, $max_value), 0);
} elseif ($current_type == 'percentage') {
$new_parts[] = (float)max(min(rtrim($part, '%'), $max_value), 0) . '%';
}
}
$new_triad = implode(',', $new_parts);
$color = "rgb($new_triad)";
$new_values = implode(',', $new_parts);
$color = $function . '(' . $new_values . ')';
} else {
// hexadecimal handling
if ($color[0] === '#') {
@@ -100,6 +155,7 @@ class HTMLPurifier_AttrDef_CSS_Color extends HTMLPurifier_AttrDef
}
return $color;
}
}
// vim: et sw=4 sts=4

View File

@@ -10,23 +10,21 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
public function __construct()
{
$this->mask = '_- ';
for ($c = 'a'; $c <= 'z'; $c++) {
$this->mask .= $c;
}
for ($c = 'A'; $c <= 'Z'; $c++) {
$this->mask .= $c;
}
for ($c = '0'; $c <= '9'; $c++) {
$this->mask .= $c;
} // cast-y, but should be fine
// special bytes used by UTF-8
for ($i = 0x80; $i <= 0xFF; $i++) {
// We don't bother excluding invalid bytes in this range,
// because the our restriction of well-formed UTF-8 will
// prevent these from ever occurring.
$this->mask .= chr($i);
}
// Lowercase letters
$l = range('a', 'z');
// Uppercase letters
$u = range('A', 'Z');
// Digits
$d = range('0', '9');
// Special bytes used by UTF-8
$b = array_map('chr', range(0x80, 0xFF));
// All valid characters for the mask
$c = array_merge($l, $u, $d, $b);
// Concatenate all valid characters into a string
// Use '_- ' as an initial value
$this->mask = array_reduce($c, function ($carry, $value) {
return $carry . $value;
}, '_- ');
/*
PHP's internal strcspn implementation is
@@ -197,7 +195,7 @@ class HTMLPurifier_AttrDef_CSS_FontFamily extends HTMLPurifier_AttrDef
// transforms don't pose a security risk (as \\ and \"
// might--these escapes are not supported by most browsers).
// We could try to be clever and use single-quote wrapping
// when there is a double quote present, but I have choosen
// when there is a double quote present, but I have chosen
// not to implement that. (NOTE: you can reduce the amount
// of escapes by one depending on what quoting style you use)
// $font = str_replace('\\', '\\5C ', $font);

View File

@@ -69,7 +69,13 @@ class HTMLPurifier_AttrDef_CSS_Number extends HTMLPurifier_AttrDef
return false;
}
$left = ltrim($left, '0');
// Remove leading zeros until positive number or a zero stays left
if (ltrim($left, '0') != '') {
$left = ltrim($left, '0');
} else {
$left = '0';
}
$right = rtrim($right, '0');
if ($right === '') {

View File

@@ -0,0 +1,46 @@
<?php
/**
* Validates a ratio as defined by the CSS spec.
*/
class HTMLPurifier_AttrDef_CSS_Ratio extends HTMLPurifier_AttrDef
{
/**
* @param string $ratio Ratio to validate
* @param HTMLPurifier_Config $config Configuration options
* @param HTMLPurifier_Context $context Context
*
* @return string|boolean
*
* @warning Some contexts do not pass $config, $context. These
* variables should not be used without checking HTMLPurifier_Length
*/
public function validate($ratio, $config, $context)
{
$ratio = $this->parseCDATA($ratio);
$parts = explode('/', $ratio, 2);
$length = count($parts);
if ($length < 1 || $length > 2) {
return false;
}
$num = new \HTMLPurifier_AttrDef_CSS_Number();
if ($length === 1) {
return $num->validate($parts[0], $config, $context);
}
$num1 = $num->validate($parts[0], $config, $context);
$num2 = $num->validate($parts[1], $config, $context);
if ($num1 === false || $num2 === false) {
return false;
}
return $num1 . '/' . $num2;
}
}
// vim: et sw=4 sts=4

View File

@@ -7,7 +7,7 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
{
/**
* @type bool
* @type string
*/
protected $name;
@@ -17,7 +17,7 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
public $minimized = true;
/**
* @param bool $name
* @param bool|string $name
*/
public function __construct($name = false)
{

View File

@@ -0,0 +1,16 @@
<?php
class HTMLPurifier_AttrDef_HTML_ContentEditable extends HTMLPurifier_AttrDef
{
public function validate($string, $config, $context)
{
$allowed = array('false');
if ($config->get('HTML.Trusted')) {
$allowed = array('', 'true', 'false');
}
$enum = new HTMLPurifier_AttrDef_Enum($allowed);
return $enum->validate($string, $config, $context);
}
}

View File

@@ -25,12 +25,7 @@ class HTMLPurifier_AttrDef_HTML_LinkTypes extends HTMLPurifier_AttrDef
'rev' => 'AllowedRev'
);
if (!isset($configLookup[$name])) {
trigger_error(
'Unrecognized attribute name for link ' .
'relationship.',
E_USER_ERROR
);
return;
throw new Exception('Unrecognized attribute name for link relationship.');
}
$this->name = $configLookup[$name];
}

View File

@@ -63,24 +63,18 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// This doesn't match I18N domain names, but we don't have proper IRI support,
// so force users to insert Punycode.
// There is not a good sense in which underscores should be
// allowed, since it's technically not! (And if you go as
// far to allow everything as specified by the DNS spec...
// well, that's literally everything, modulo some space limits
// for the components and the overall name (which, by the way,
// we are NOT checking!). So we (arbitrarily) decide this:
// let's allow underscores wherever we would have allowed
// hyphens, if they are enabled. This is a pretty good match
// for browser behavior, for example, a large number of browsers
// cannot handle foo_.example.com, but foo_bar.example.com is
// fairly well supported.
// Underscores defined as Unreserved Characters in RFC 3986 are
// allowed in a URI. There are cases where we want to consider a
// URI containing "_" such as "_dmarc.example.com".
// Underscores are not allowed in the default. If you want to
// allow it, set Core.AllowHostnameUnderscore to true.
$underscore = $config->get('Core.AllowHostnameUnderscore') ? '_' : '';
// Based off of RFC 1738, but amended so that
// as per RFC 3696, the top label need only not be all numeric.
// The productions describing this are:
$a = '[a-z]'; // alpha
$an = '[a-z0-9]'; // alphanum
$an = "[a-z0-9$underscore]"; // alphanum
$and = "[a-z0-9-$underscore]"; // alphanum | "-"
// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
$domainlabel = "$an(?:$and*$an)?";
@@ -97,12 +91,16 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// PHP 5.3 and later support this functionality natively
if (function_exists('idn_to_ascii')) {
return idn_to_ascii($string);
if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) {
$string = idn_to_ascii($string, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
} else {
$string = idn_to_ascii($string);
}
// If we have Net_IDNA2 support, we can support IRIs by
// punycoding them. (This is the most portable thing to do,
// since otherwise we have to assume browsers support
} elseif ($config->get('Core.EnableIDNA')) {
} elseif ($config->get('Core.EnableIDNA') && class_exists('Net_IDNA2')) {
$idna = new Net_IDNA2(array('encoding' => 'utf8', 'overlong' => false, 'strict' => true));
// we need to encode each period separately
$parts = explode('.', $string);
@@ -123,13 +121,14 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
}
}
$string = implode('.', $new_parts);
if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
return $string;
}
} catch (Exception $e) {
// XXX error reporting
}
}
// Try again
if (preg_match("/^($domainlabel\.)*$toplabel\.?$/i", $string)) {
return $string;
}
return false;
}
}

View File

@@ -37,7 +37,7 @@ class HTMLPurifier_AttrDef_URI_IPv6 extends HTMLPurifier_AttrDef_URI_IPv4
}
}
// IPv4-compatiblity check
// IPv4-compatibility check
if (preg_match('#(?<=:' . ')' . $this->ip4 . '$#s', $aIP, $find)) {
$aIP = substr($aIP, 0, 0 - strlen($find[0]));
$ip = explode('.', $find[0]);

View File

@@ -3,7 +3,7 @@
// this MUST be placed in post, as it assumes that any value in dir is valid
/**
* Post-trasnform that ensures that bdo tags have the dir attribute set.
* Post-transform that ensures that bdo tags have the dir attribute set.
*/
class HTMLPurifier_AttrTransform_BdoDir extends HTMLPurifier_AttrTransform
{

View File

@@ -8,6 +8,11 @@
class HTMLPurifier_AttrTransform_NameSync extends HTMLPurifier_AttrTransform
{
/**
* @type HTMLPurifier_AttrDef_HTML_ID
*/
public $idDef;
public function __construct()
{
$this->idDef = new HTMLPurifier_AttrDef_HTML_ID();

View File

@@ -24,6 +24,11 @@ class HTMLPurifier_AttrTransform_SafeParam extends HTMLPurifier_AttrTransform
*/
private $uri;
/**
* @type HTMLPurifier_AttrDef_Enum
*/
public $wmode;
public function __construct()
{
$this->uri = new HTMLPurifier_AttrDef_URI(true); // embedded

View File

@@ -33,7 +33,11 @@ class HTMLPurifier_AttrTransform_TargetBlank extends HTMLPurifier_AttrTransform
// XXX Kind of inefficient
$url = $this->parser->parse($attr['href']);
$scheme = $url->getSchemeObj($config, $context);
// Ignore invalid schemes (e.g. `javascript:`)
if (!($scheme = $url->getSchemeObj($config, $context))) {
return $attr;
}
if ($scheme->browsable && !$url->isBenign($config, $context)) {
$attr['target'] = '_blank';

View File

@@ -0,0 +1,37 @@
<?php
// must be called POST validation
/**
* Adds rel="noopener" to any links which target a different window
* than the current one. This is used to prevent malicious websites
* from silently replacing the original window, which could be used
* to do phishing.
* This transform is controlled by %HTML.TargetNoopener.
*/
class HTMLPurifier_AttrTransform_TargetNoopener extends HTMLPurifier_AttrTransform
{
/**
* @param array $attr
* @param HTMLPurifier_Config $config
* @param HTMLPurifier_Context $context
* @return array
*/
public function transform($attr, $config, $context)
{
if (isset($attr['rel'])) {
$rels = explode(' ', $attr['rel']);
} else {
$rels = array();
}
if (isset($attr['target']) && !in_array('noopener', $rels)) {
$rels[] = 'noopener';
}
if (!empty($rels) || isset($attr['rel'])) {
$attr['rel'] = implode(' ', $rels);
}
return $attr;
}
}

View File

@@ -41,6 +41,7 @@ class HTMLPurifier_AttrTypes
$this->info['IAlign'] = self::makeEnum('top,middle,bottom,left,right');
$this->info['LAlign'] = self::makeEnum('top,bottom,left,right');
$this->info['FrameTarget'] = new HTMLPurifier_AttrDef_HTML_FrameTarget();
$this->info['ContentEditable'] = new HTMLPurifier_AttrDef_HTML_ContentEditable();
// unimplemented aliases
$this->info['ContentType'] = new HTMLPurifier_AttrDef_Text();
@@ -76,7 +77,7 @@ class HTMLPurifier_AttrTypes
}
if (!isset($this->info[$type])) {
trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR);
throw new Exception('Cannot retrieve undefined attribute type ' . $type);
return;
}
return $this->info[$type]->make($string);

View File

@@ -135,7 +135,7 @@ class HTMLPurifier_AttrValidator
// we'd also want slightly more complicated substitution
// involving an array as the return value,
// although we're not sure how colliding attributes would
// resolve (certain ones would be completely overriden,
// resolve (certain ones would be completely overridden,
// others would prepend themselves).
}

View File

@@ -5,7 +5,7 @@ if (!defined('HTMLPURIFIER_PREFIX')) {
define('HTMLPURIFIER_PREFIX', realpath(dirname(__FILE__) . '/..'));
}
// accomodations for versions earlier than 5.0.2
// accommodations for versions earlier than 5.0.2
// borrowed from PHP_Compat, LGPL licensed, by Aidan Lister <aidan@php.net>
if (!defined('PHP_EOL')) {
switch (strtoupper(substr(PHP_OS, 0, 3))) {
@@ -79,44 +79,11 @@ class HTMLPurifier_Bootstrap
public static function registerAutoload()
{
$autoload = array('HTMLPurifier_Bootstrap', 'autoload');
if (($funcs = spl_autoload_functions()) === false) {
if (spl_autoload_functions() === false) {
spl_autoload_register($autoload);
} elseif (function_exists('spl_autoload_unregister')) {
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
// prepend flag exists, no need for shenanigans
spl_autoload_register($autoload, true, true);
} else {
$buggy = version_compare(PHP_VERSION, '5.2.11', '<');
$compat = version_compare(PHP_VERSION, '5.1.2', '<=') &&
version_compare(PHP_VERSION, '5.1.0', '>=');
foreach ($funcs as $func) {
if ($buggy && is_array($func)) {
// :TRICKY: There are some compatibility issues and some
// places where we need to error out
$reflector = new ReflectionMethod($func[0], $func[1]);
if (!$reflector->isStatic()) {
throw new Exception(
'HTML Purifier autoloader registrar is not compatible
with non-static object methods due to PHP Bug #44144;
Please do not use HTMLPurifier.autoload.php (or any
file that includes this file); instead, place the code:
spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\'))
after your own autoloaders.'
);
}
// Suprisingly, spl_autoload_register supports the
// Class::staticMethod callback format, although call_user_func doesn't
if ($compat) {
$func = implode('::', $func);
}
}
spl_autoload_unregister($func);
}
spl_autoload_register($autoload);
foreach ($funcs as $func) {
spl_autoload_register($func);
}
}
} else {
// prepend flag exists, no need for shenanigans
spl_autoload_register($autoload, true, true);
}
}
}

View File

@@ -13,7 +13,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
* Assoc array of attribute name to definition object.
* @type HTMLPurifier_AttrDef[]
*/
public $info = array();
public $info = [];
/**
* Constructs the info array. The meat of this class.
@@ -22,7 +22,12 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
protected function doSetup($config)
{
$this->info['text-align'] = new HTMLPurifier_AttrDef_Enum(
array('left', 'right', 'center', 'justify'),
['left', 'right', 'center', 'justify'],
false
);
$this->info['direction'] = new HTMLPurifier_AttrDef_Enum(
['ltr', 'rtl'],
false
);
@@ -31,7 +36,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['border-right-style'] =
$this->info['border-left-style'] =
$this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum(
array(
[
'none',
'hidden',
'dotted',
@@ -42,42 +47,42 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'ridge',
'inset',
'outset'
),
],
false
);
$this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style);
$this->info['clear'] = new HTMLPurifier_AttrDef_Enum(
array('none', 'left', 'right', 'both'),
['none', 'left', 'right', 'both'],
false
);
$this->info['float'] = new HTMLPurifier_AttrDef_Enum(
array('none', 'left', 'right'),
['none', 'left', 'right'],
false
);
$this->info['font-style'] = new HTMLPurifier_AttrDef_Enum(
array('normal', 'italic', 'oblique'),
['normal', 'italic', 'oblique'],
false
);
$this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum(
array('normal', 'small-caps'),
['normal', 'small-caps'],
false
);
$uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_Enum(array('none')),
[
new HTMLPurifier_AttrDef_Enum(['none']),
new HTMLPurifier_AttrDef_CSS_URI()
)
]
);
$this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum(
array('inside', 'outside'),
['inside', 'outside'],
false
);
$this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum(
array(
[
'disc',
'circle',
'square',
@@ -87,7 +92,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'lower-alpha',
'upper-alpha',
'none'
),
],
false
);
$this->info['list-style-image'] = $uri_or_none;
@@ -95,30 +100,44 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config);
$this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum(
array('capitalize', 'uppercase', 'lowercase', 'none'),
['capitalize', 'uppercase', 'lowercase', 'none'],
false
);
$this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color();
$this->info['background-image'] = $uri_or_none;
$this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum(
array('repeat', 'repeat-x', 'repeat-y', 'no-repeat')
['repeat', 'repeat-x', 'repeat-y', 'no-repeat']
);
$this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum(
array('scroll', 'fixed')
['scroll', 'fixed']
);
$this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition();
$this->info['background-size'] = new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_Enum(
[
'auto',
'cover',
'contain',
]
),
new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_CSS_Length()
]
);
$border_color =
$this->info['border-top-color'] =
$this->info['border-bottom-color'] =
$this->info['border-left-color'] =
$this->info['border-right-color'] =
$this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_Enum(array('transparent')),
[
new HTMLPurifier_AttrDef_Enum(['transparent']),
new HTMLPurifier_AttrDef_CSS_Color()
)
]
);
$this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config);
@@ -130,32 +149,32 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['border-bottom-width'] =
$this->info['border-left-width'] =
$this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')),
[
new HTMLPurifier_AttrDef_Enum(['thin', 'medium', 'thick']),
new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative
)
]
);
$this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width);
$this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_Enum(array('normal')),
[
new HTMLPurifier_AttrDef_Enum(['normal']),
new HTMLPurifier_AttrDef_CSS_Length()
)
]
);
$this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_Enum(array('normal')),
[
new HTMLPurifier_AttrDef_Enum(['normal']),
new HTMLPurifier_AttrDef_CSS_Length()
)
]
);
$this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_Enum(
array(
[
'xx-small',
'x-small',
'small',
@@ -165,20 +184,20 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'xx-large',
'larger',
'smaller'
)
]
),
new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_CSS_Length()
)
]
);
$this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_Enum(array('normal')),
[
new HTMLPurifier_AttrDef_Enum(['normal']),
new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true)
)
]
);
$margin =
@@ -186,11 +205,11 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['margin-bottom'] =
$this->info['margin-left'] =
$this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_Enum(array('auto'))
)
new HTMLPurifier_AttrDef_Enum(['auto'])
]
);
$this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin);
@@ -201,27 +220,40 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['padding-bottom'] =
$this->info['padding-left'] =
$this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true)
)
]
);
$this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding);
$this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage()
)
]
);
$trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('auto'))
)
new HTMLPurifier_AttrDef_Enum(['auto'])
]
);
$trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
]
);
$trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(['none'])
]
);
$max = $config->get('CSS.MaxImgLength');
@@ -233,22 +265,73 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(array('auto'))
)
new HTMLPurifier_AttrDef_Enum(['auto'])
]
),
// For everyone else:
$trusted_wh
);
$this->info['min-width'] =
$this->info['min-height'] =
$max === null ?
$trusted_min_wh :
new HTMLPurifier_AttrDef_Switch(
'img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
// For everyone else:
$trusted_min_wh
);
$this->info['max-width'] =
$this->info['max-height'] =
$max === null ?
$trusted_max_wh :
new HTMLPurifier_AttrDef_Switch(
'img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(
[
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(['none'])
]
),
// For everyone else:
$trusted_max_wh
);
$this->info['aspect-ratio'] = new HTMLPurifier_AttrDef_CSS_Multiple(
new HTMLPurifier_AttrDef_CSS_Composite([
new HTMLPurifier_AttrDef_CSS_Ratio(),
new HTMLPurifier_AttrDef_Enum(['auto']),
])
);
// text-decoration and related shorthands
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
$this->info['text-decoration-line'] = new HTMLPurifier_AttrDef_Enum(
['none', 'underline', 'overline', 'line-through']
);
$this->info['text-decoration-style'] = new HTMLPurifier_AttrDef_Enum(
['solid', 'double', 'dotted', 'dashed', 'wavy']
);
$this->info['text-decoration-color'] = new HTMLPurifier_AttrDef_CSS_Color();
$this->info['text-decoration-thickness'] = new HTMLPurifier_AttrDef_CSS_Composite([
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_Enum(['auto', 'from-font'])
]);
$this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily();
// this could use specialized code
$this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum(
array(
[
'normal',
'bold',
'bolder',
@@ -262,7 +345,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'700',
'800',
'900'
),
],
false
);
@@ -278,21 +361,21 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
$this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config);
$this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum(
array('collapse', 'separate')
['collapse', 'separate']
);
$this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum(
array('top', 'bottom')
['top', 'bottom']
);
$this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum(
array('auto', 'fixed')
['auto', 'fixed']
);
$this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_Enum(
array(
[
'baseline',
'sub',
'super',
@@ -301,11 +384,11 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'middle',
'bottom',
'text-bottom'
)
]
),
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage()
)
]
);
$this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2);
@@ -313,7 +396,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
// These CSS properties don't work on many browsers, but we live
// in THE FUTURE!
$this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(
array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line')
['nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line']
);
if ($config->get('CSS.Proprietary')) {
@@ -360,21 +443,21 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
// more CSS3
$this->info['page-break-after'] =
$this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum(
array(
[
'auto',
'always',
'avoid',
'left',
'right'
)
]
);
$this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid'));
$this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(['auto', 'avoid']);
$border_radius = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Percentage(true), // disallow negative
new HTMLPurifier_AttrDef_CSS_Length('0') // disallow negative
));
]);
$this->info['border-top-left-radius'] =
$this->info['border-top-right-radius'] =
@@ -391,7 +474,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
protected function doSetupTricky($config)
{
$this->info['display'] = new HTMLPurifier_AttrDef_Enum(
array(
[
'inline',
'block',
'list-item',
@@ -410,12 +493,12 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'table-cell',
'table-caption',
'none'
)
]
);
$this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(
array('visible', 'hidden', 'collapse')
['visible', 'hidden', 'collapse']
);
$this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll'));
$this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(['visible', 'hidden', 'auto', 'scroll']);
$this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
}
@@ -425,23 +508,23 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
protected function doSetupTrusted($config)
{
$this->info['position'] = new HTMLPurifier_AttrDef_Enum(
array('static', 'relative', 'absolute', 'fixed')
['static', 'relative', 'absolute', 'fixed']
);
$this->info['top'] =
$this->info['left'] =
$this->info['right'] =
$this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Length(),
new HTMLPurifier_AttrDef_CSS_Percentage(),
new HTMLPurifier_AttrDef_Enum(array('auto')),
)
new HTMLPurifier_AttrDef_Enum(['auto']),
]
);
$this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_Integer(),
new HTMLPurifier_AttrDef_Enum(array('auto')),
)
new HTMLPurifier_AttrDef_Enum(['auto']),
]
);
}

View File

@@ -45,7 +45,7 @@ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef
protected function _compileRegex()
{
$raw = str_replace(' ', '', $this->dtd_regex);
if ($raw{0} != '(') {
if ($raw[0] != '(') {
$raw = "($raw)";
}
$el = '[#a-zA-Z0-9_.-]+';

View File

@@ -22,6 +22,8 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef
// XXX: This whole business with 'wrap' is all a bit unsatisfactory
public $elements = array('li' => true, 'ul' => true, 'ol' => true);
public $whitespace;
/**
* @param array $children
* @param HTMLPurifier_Config $config
@@ -50,7 +52,7 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef
// a little sanity check to make sure it's not ALL whitespace
$all_whitespace = true;
$current_li = false;
$current_li = null;
foreach ($children as $node) {
if (!empty($node->is_whitespace)) {
@@ -71,7 +73,7 @@ class HTMLPurifier_ChildDef_List extends HTMLPurifier_ChildDef
// to handle non-list elements; non-list elements should
// not be appended to an existing li; only li created
// for non-list. This distinction is not currently made.
if ($current_li === false) {
if ($current_li === null) {
$current_li = new HTMLPurifier_Node_Element('li');
$result[] = $current_li;
}

View File

@@ -164,7 +164,7 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
}
}
if (empty($content)) {
if (empty($content) && $thead === false && $tfoot === false) {
return false;
}
@@ -190,6 +190,9 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
$current_tr_tbody = null;
foreach($content as $node) {
if (!isset($node->name)) {
continue;
}
switch ($node->name) {
case 'tbody':
$current_tr_tbody = null;
@@ -203,7 +206,7 @@ class HTMLPurifier_ChildDef_Table extends HTMLPurifier_ChildDef
$current_tr_tbody->children[] = $node;
break;
case '#PCDATA':
assert($node->is_whitespace);
//assert($node->is_whitespace);
if ($current_tr_tbody === null) {
$ret[] = $node;
} else {

View File

@@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.8.0';
public $version = '4.18.0';
/**
* Whether or not to automatically finalize
@@ -333,7 +333,7 @@ class HTMLPurifier_Config
}
// Raw type might be negative when using the fully optimized form
// of stdclass, which indicates allow_null == true
// of stdClass, which indicates allow_null == true
$rtype = is_int($def) ? $def : $def->type;
if ($rtype < 0) {
$type = -$rtype;
@@ -408,7 +408,7 @@ class HTMLPurifier_Config
* maybeGetRawHTMLDefinition, which is more explicitly
* named, instead.
*
* @return HTMLPurifier_HTMLDefinition
* @return HTMLPurifier_HTMLDefinition|null
*/
public function getHTMLDefinition($raw = false, $optimized = false)
{
@@ -427,7 +427,7 @@ class HTMLPurifier_Config
* maybeGetRawCSSDefinition, which is more explicitly
* named, instead.
*
* @return HTMLPurifier_CSSDefinition
* @return HTMLPurifier_CSSDefinition|null
*/
public function getCSSDefinition($raw = false, $optimized = false)
{
@@ -446,7 +446,7 @@ class HTMLPurifier_Config
* maybeGetRawURIDefinition, which is more explicitly
* named, instead.
*
* @return HTMLPurifier_URIDefinition
* @return HTMLPurifier_URIDefinition|null
*/
public function getURIDefinition($raw = false, $optimized = false)
{
@@ -468,7 +468,7 @@ class HTMLPurifier_Config
* maybe semantics is the "right thing to do."
*
* @throws HTMLPurifier_Exception
* @return HTMLPurifier_Definition
* @return HTMLPurifier_Definition|null
*/
public function getDefinition($type, $raw = false, $optimized = false)
{
@@ -647,7 +647,7 @@ class HTMLPurifier_Config
}
/**
* @return HTMLPurifier_HTMLDefinition
* @return HTMLPurifier_HTMLDefinition|null
*/
public function maybeGetRawHTMLDefinition()
{
@@ -655,7 +655,7 @@ class HTMLPurifier_Config
}
/**
* @return HTMLPurifier_CSSDefinition
* @return HTMLPurifier_CSSDefinition|null
*/
public function maybeGetRawCSSDefinition()
{
@@ -663,7 +663,7 @@ class HTMLPurifier_Config
}
/**
* @return HTMLPurifier_URIDefinition
* @return HTMLPurifier_URIDefinition|null
*/
public function maybeGetRawURIDefinition()
{
@@ -803,7 +803,7 @@ class HTMLPurifier_Config
if ($index !== false) {
$array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array();
}
$mq = $mq_fix && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc();
$mq = $mq_fix && version_compare(PHP_VERSION, '7.4.0', '<') && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc();
$allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema);
$ret = array();
@@ -890,7 +890,7 @@ class HTMLPurifier_Config
// zip(tail(trace), trace) -- but PHP is not Haskell har har
for ($i = 0, $c = count($trace); $i < $c - 1; $i++) {
// XXX this is not correct on some versions of HTML Purifier
if ($trace[$i + 1]['class'] === 'HTMLPurifier_Config') {
if (isset($trace[$i + 1]['class']) && $trace[$i + 1]['class'] === 'HTMLPurifier_Config') {
continue;
}
$frame = $trace[$i];
@@ -898,7 +898,11 @@ class HTMLPurifier_Config
break;
}
}
trigger_error($msg . $extra, $no);
if ($no == E_USER_ERROR) {
throw new Exception($msg . $extra);
} else {
trigger_error($msg . $extra, $no);
}
}
/**

View File

@@ -24,11 +24,11 @@ class HTMLPurifier_ConfigSchema
*
* array(
* 'Namespace' => array(
* 'Directive' => new stdclass(),
* 'Directive' => new stdClass(),
* )
* )
*
* The stdclass may have the following properties:
* The stdClass may have the following properties:
*
* - If isAlias isn't set:
* - type: Integer type of directive, see HTMLPurifier_VarParser for definitions
@@ -39,8 +39,8 @@ class HTMLPurifier_ConfigSchema
* - namespace: Namespace this directive aliases to
* - name: Directive name this directive aliases to
*
* In certain degenerate cases, stdclass will actually be an integer. In
* that case, the value is equivalent to an stdclass with the type
* In certain degenerate cases, stdClass will actually be an integer. In
* that case, the value is equivalent to an stdClass with the type
* property set to the integer. If the integer is negative, type is
* equal to the absolute value of integer, and allow_null is true.
*
@@ -72,7 +72,7 @@ class HTMLPurifier_ConfigSchema
$r = unserialize($contents);
if (!$r) {
$hash = sha1($contents);
trigger_error("Unserialization of configuration schema failed, sha1 of file was $hash", E_USER_ERROR);
throw new Exception("Unserialization of configuration schema failed, sha1 of file was $hash");
}
return $r;
}
@@ -100,12 +100,12 @@ class HTMLPurifier_ConfigSchema
* @param string $key Name of directive
* @param mixed $default Default value of directive
* @param string $type Allowed type of the directive. See
* HTMLPurifier_DirectiveDef::$type for allowed values
* HTMLPurifier_VarParser::$types for allowed values
* @param bool $allow_null Whether or not to allow null values
*/
public function add($key, $default, $type, $allow_null)
{
$obj = new stdclass();
$obj = new stdClass();
$obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type];
if ($allow_null) {
$obj->allow_null = true;
@@ -152,14 +152,14 @@ class HTMLPurifier_ConfigSchema
*/
public function addAlias($key, $new_key)
{
$obj = new stdclass;
$obj = new stdClass;
$obj->key = $new_key;
$obj->isAlias = true;
$this->info[$key] = $obj;
}
/**
* Replaces any stdclass that only has the type property with type integer.
* Replaces any stdClass that only has the type property with type integer.
*/
public function postProcess()
{

View File

@@ -66,7 +66,7 @@ class HTMLPurifier_ConfigSchema_Interchange_Directive
public $version;
/**
* ID of directive that supercedes this old directive.
* ID of directive that supersedes this old directive.
* Null if not deprecated.
* @type HTMLPurifier_ConfigSchema_Interchange_Id
*/

View File

@@ -5,10 +5,10 @@ DEFAULT: ''
--DESCRIPTION--
Temporary prefix for IDs used in conjunction with %Attr.IDPrefix. If you
need to allow multiple sets of user content on web page, you may need to
have a seperate prefix that changes with each iteration. This way,
seperately submitted user content displayed on the same page doesn't
have a separate prefix that changes with each iteration. This way,
separately submitted user content displayed on the same page doesn't
clobber each other. Ideal values are unique identifiers for the content it
represents (i.e. the id of the row in the database). Be sure to add a
seperator (like an underscore) at the end. Warning: this directive will
separator (like an underscore) at the end. Warning: this directive will
not work unless %Attr.IDPrefix is set to a non-empty value!
--# vim: et sw=4 sts=4

View File

@@ -6,7 +6,7 @@ DEFAULT: false
<p>
When enabled, HTML Purifier will treat any elements that contain only
non-breaking spaces as well as regular whitespace as empty, and remove
them when %AutoForamt.RemoveEmpty is enabled.
them when %AutoFormat.RemoveEmpty is enabled.
</p>
<p>
See %AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions for a list of elements

View File

@@ -1,6 +1,6 @@
CSS.MaxImgLength
TYPE: string/null
DEFAULT: '1200px'
DEFAULT: null
VERSION: 3.1.1
--DESCRIPTION--
<p>

View File

@@ -0,0 +1,16 @@
Core.AggressivelyRemoveScript
TYPE: bool
VERSION: 4.9.0
DEFAULT: true
--DESCRIPTION--
<p>
This directive enables aggressive pre-filter removal of
script tags. This is not necessary for security,
but it can help work around a bug in libxml where embedded
HTML elements inside script sections cause the parser to
choke. To revert to pre-4.9.0 behavior, set this to false.
This directive has no effect if %Core.Trusted is true,
%Core.RemoveScriptContents is false, or %Core.HiddenElements
does not contain script.
</p>
--# vim: et sw=4 sts=4

View File

@@ -0,0 +1,12 @@
Core.AllowParseManyTags
TYPE: bool
DEFAULT: false
VERSION: 4.10.1
--DESCRIPTION--
<p>
This directive allows parsing of many nested tags.
If you set true, relaxes any hardcoded limit from the parser.
However, in that case it may cause a Dos attack.
Be careful when enabling it.
</p>
--# vim: et sw=4 sts=4

View File

@@ -3,23 +3,154 @@ TYPE: hash
VERSION: 2.0.0
--DEFAULT--
array (
'maroon' => '#800000',
'red' => '#FF0000',
'orange' => '#FFA500',
'yellow' => '#FFFF00',
'olive' => '#808000',
'purple' => '#800080',
'fuchsia' => '#FF00FF',
'white' => '#FFFFFF',
'lime' => '#00FF00',
'green' => '#008000',
'navy' => '#000080',
'blue' => '#0000FF',
'aliceblue' => '#F0F8FF',
'antiquewhite' => '#FAEBD7',
'aqua' => '#00FFFF',
'teal' => '#008080',
'aquamarine' => '#7FFFD4',
'azure' => '#F0FFFF',
'beige' => '#F5F5DC',
'bisque' => '#FFE4C4',
'black' => '#000000',
'silver' => '#C0C0C0',
'blanchedalmond' => '#FFEBCD',
'blue' => '#0000FF',
'blueviolet' => '#8A2BE2',
'brown' => '#A52A2A',
'burlywood' => '#DEB887',
'cadetblue' => '#5F9EA0',
'chartreuse' => '#7FFF00',
'chocolate' => '#D2691E',
'coral' => '#FF7F50',
'cornflowerblue' => '#6495ED',
'cornsilk' => '#FFF8DC',
'crimson' => '#DC143C',
'cyan' => '#00FFFF',
'darkblue' => '#00008B',
'darkcyan' => '#008B8B',
'darkgoldenrod' => '#B8860B',
'darkgray' => '#A9A9A9',
'darkgrey' => '#A9A9A9',
'darkgreen' => '#006400',
'darkkhaki' => '#BDB76B',
'darkmagenta' => '#8B008B',
'darkolivegreen' => '#556B2F',
'darkorange' => '#FF8C00',
'darkorchid' => '#9932CC',
'darkred' => '#8B0000',
'darksalmon' => '#E9967A',
'darkseagreen' => '#8FBC8F',
'darkslateblue' => '#483D8B',
'darkslategray' => '#2F4F4F',
'darkslategrey' => '#2F4F4F',
'darkturquoise' => '#00CED1',
'darkviolet' => '#9400D3',
'deeppink' => '#FF1493',
'deepskyblue' => '#00BFFF',
'dimgray' => '#696969',
'dimgrey' => '#696969',
'dodgerblue' => '#1E90FF',
'firebrick' => '#B22222',
'floralwhite' => '#FFFAF0',
'forestgreen' => '#228B22',
'fuchsia' => '#FF00FF',
'gainsboro' => '#DCDCDC',
'ghostwhite' => '#F8F8FF',
'gold' => '#FFD700',
'goldenrod' => '#DAA520',
'gray' => '#808080',
'grey' => '#808080',
'green' => '#008000',
'greenyellow' => '#ADFF2F',
'honeydew' => '#F0FFF0',
'hotpink' => '#FF69B4',
'indianred' => '#CD5C5C',
'indigo' => '#4B0082',
'ivory' => '#FFFFF0',
'khaki' => '#F0E68C',
'lavender' => '#E6E6FA',
'lavenderblush' => '#FFF0F5',
'lawngreen' => '#7CFC00',
'lemonchiffon' => '#FFFACD',
'lightblue' => '#ADD8E6',
'lightcoral' => '#F08080',
'lightcyan' => '#E0FFFF',
'lightgoldenrodyellow' => '#FAFAD2',
'lightgray' => '#D3D3D3',
'lightgrey' => '#D3D3D3',
'lightgreen' => '#90EE90',
'lightpink' => '#FFB6C1',
'lightsalmon' => '#FFA07A',
'lightseagreen' => '#20B2AA',
'lightskyblue' => '#87CEFA',
'lightslategray' => '#778899',
'lightslategrey' => '#778899',
'lightsteelblue' => '#B0C4DE',
'lightyellow' => '#FFFFE0',
'lime' => '#00FF00',
'limegreen' => '#32CD32',
'linen' => '#FAF0E6',
'magenta' => '#FF00FF',
'maroon' => '#800000',
'mediumaquamarine' => '#66CDAA',
'mediumblue' => '#0000CD',
'mediumorchid' => '#BA55D3',
'mediumpurple' => '#9370DB',
'mediumseagreen' => '#3CB371',
'mediumslateblue' => '#7B68EE',
'mediumspringgreen' => '#00FA9A',
'mediumturquoise' => '#48D1CC',
'mediumvioletred' => '#C71585',
'midnightblue' => '#191970',
'mintcream' => '#F5FFFA',
'mistyrose' => '#FFE4E1',
'moccasin' => '#FFE4B5',
'navajowhite' => '#FFDEAD',
'navy' => '#000080',
'oldlace' => '#FDF5E6',
'olive' => '#808000',
'olivedrab' => '#6B8E23',
'orange' => '#FFA500',
'orangered' => '#FF4500',
'orchid' => '#DA70D6',
'palegoldenrod' => '#EEE8AA',
'palegreen' => '#98FB98',
'paleturquoise' => '#AFEEEE',
'palevioletred' => '#DB7093',
'papayawhip' => '#FFEFD5',
'peachpuff' => '#FFDAB9',
'peru' => '#CD853F',
'pink' => '#FFC0CB',
'plum' => '#DDA0DD',
'powderblue' => '#B0E0E6',
'purple' => '#800080',
'rebeccapurple' => '#663399',
'red' => '#FF0000',
'rosybrown' => '#BC8F8F',
'royalblue' => '#4169E1',
'saddlebrown' => '#8B4513',
'salmon' => '#FA8072',
'sandybrown' => '#F4A460',
'seagreen' => '#2E8B57',
'seashell' => '#FFF5EE',
'sienna' => '#A0522D',
'silver' => '#C0C0C0',
'skyblue' => '#87CEEB',
'slateblue' => '#6A5ACD',
'slategray' => '#708090',
'slategrey' => '#708090',
'snow' => '#FFFAFA',
'springgreen' => '#00FF7F',
'steelblue' => '#4682B4',
'tan' => '#D2B48C',
'teal' => '#008080',
'thistle' => '#D8BFD8',
'tomato' => '#FF6347',
'turquoise' => '#40E0D0',
'violet' => '#EE82EE',
'wheat' => '#F5DEB3',
'white' => '#FFFFFF',
'whitesmoke' => '#F5F5F5',
'yellow' => '#FFFF00',
'yellowgreen' => '#9ACD32'
)
--DESCRIPTION--

View File

@@ -7,7 +7,8 @@ This parameter determines whether or not the filter should convert
input that is a full document with html and body tags to a fragment
of just the contents of a body tag. This parameter is simply something
HTML Purifier can do during an edge-case: for most inputs, this
processing is not necessary.
processing is not necessary. Warning: Full HTML purification has not
been implemented. See GitHub issue #7.
--ALIASES--
Core.AcceptFullDocuments

View File

@@ -8,6 +8,6 @@ converting all non-ASCII characters into decimal numeric entities before
converting it to its native encoding. This means that even characters that
can be expressed in the non-UTF-8 encoding will be entity-ized, which can
be a real downer for encodings like Big5. It also assumes that the ASCII
repetoire is available, although this is the case for almost all encodings.
repertoire is available, although this is the case for almost all encodings.
Anyway, use UTF-8!
--# vim: et sw=4 sts=4

View File

@@ -0,0 +1,36 @@
Core.LegacyEntityDecoder
TYPE: bool
VERSION: 4.9.0
DEFAULT: false
--DESCRIPTION--
<p>
Prior to HTML Purifier 4.9.0, entities were decoded by performing
a global search replace for all entities whose decoded versions
did not have special meanings under HTML, and replaced them with
their decoded versions. We would match all entities, even if they did
not have a trailing semicolon, but only if there weren't any trailing
alphanumeric characters.
</p>
<table>
<tr><th>Original</th><th>Text</th><th>Attribute</th></tr>
<tr><td>&amp;yen;</td><td>&yen;</td><td>&yen;</td></tr>
<tr><td>&amp;yen</td><td>&yen;</td><td>&yen;</td></tr>
<tr><td>&amp;yena</td><td>&amp;yena</td><td>&amp;yena</td></tr>
<tr><td>&amp;yen=</td><td>&yen;=</td><td>&yen;=</td></tr>
</table>
<p>
In HTML Purifier 4.9.0, we changed the behavior of entity parsing
to match entities that had missing trailing semicolons in less
cases, to more closely match HTML5 parsing behavior:
</p>
<table>
<tr><th>Original</th><th>Text</th><th>Attribute</th></tr>
<tr><td>&amp;yen;</td><td>&yen;</td><td>&yen;</td></tr>
<tr><td>&amp;yen</td><td>&yen;</td><td>&yen;</td></tr>
<tr><td>&amp;yena</td><td>&yen;a</td><td>&amp;yena</td></tr>
<tr><td>&amp;yen=</td><td>&yen;=</td><td>&amp;yen=</td></tr>
</table>
<p>
This flag reverts back to pre-HTML Purifier 4.9.0 behavior.
</p>
--# vim: et sw=4 sts=4

View File

@@ -16,7 +16,7 @@ DEFAULT: NULL
</dd>
<dt><em>string</em> lexer identifier</dt>
<dd>
This is a slim way of manually overridding the implementation.
This is a slim way of manually overriding the implementation.
Currently recognized values are: DOMLex (the default PHP5
implementation)
and DirectLex (the default PHP4 implementation). Only use this if

View File

@@ -0,0 +1,10 @@
Core.RemoveBlanks
TYPE: bool
DEFAULT: false
VERSION: 4.18
--DESCRIPTION--
<p>
If set to true, blank nodes will be removed. This can be useful for maintaining
backwards compatibility when upgrading from previous versions of PHP.
</p>
--# vim: et sw=4 sts=4

View File

@@ -0,0 +1,11 @@
HTML.Forms
TYPE: bool
VERSION: 4.13.0
DEFAULT: false
--DESCRIPTION--
<p>
Whether or not to permit form elements in the user input, regardless of
%HTML.Trusted value. Please be very careful when using this functionality, as
enabling forms in untrusted documents may allow for phishing attacks.
</p>
--# vim: et sw=4 sts=4

View File

@@ -1,6 +1,6 @@
HTML.MaxImgLength
TYPE: int/null
DEFAULT: 1200
DEFAULT: null
VERSION: 3.1.1
--DESCRIPTION--
<p>

View File

@@ -6,7 +6,7 @@ DEFAULT: false
<p>
Whether or not to permit iframe tags in untrusted documents. This
directive must be accompanied by a whitelist of permitted iframes,
such as %URI.SafeIframeRegexp, otherwise it will fatally error.
such as %URI.SafeIframeRegexp or %URI.SafeIframeHosts, otherwise it will fatally error.
This directive has no effect on strict doctypes, as iframes are not
valid.
</p>

View File

@@ -0,0 +1,10 @@
--# vim: et sw=4 sts=4
HTML.TargetNoopener
TYPE: bool
VERSION: 4.8.0
DEFAULT: TRUE
--DESCRIPTION--
If enabled, noopener rel attributes are added to links which have
a target attribute associated with them. This prevents malicious
destinations from overwriting the original window.
--# vim: et sw=4 sts=4

View File

@@ -0,0 +1,7 @@
URI.AllowedSymbols
TYPE: string/null
DEFAULT: '!$&\'()*+,;='
--DESCRIPTION--
If a system permits templated URLs, then the URI encoder may need extra
hints about which symbols to preserve.
--# vim: et sw=4 sts=4

View File

@@ -1,5 +1,5 @@
URI.DefaultScheme
TYPE: string
TYPE: string/null
DEFAULT: 'http'
--DESCRIPTION--
@@ -7,4 +7,9 @@ DEFAULT: 'http'
Defines through what scheme the output will be served, in order to
select the proper object validator when no scheme information is present.
</p>
<p>
Starting with HTML Purifier 4.9.0, the default scheme can be null, in
which case we reject all URIs which do not have explicit schemes.
</p>
--# vim: et sw=4 sts=4

View File

@@ -0,0 +1,14 @@
URI.SafeIframeHosts
TYPE: lookup/null
DEFAULT: null
--DESCRIPTION--
<p>
A whitelist which indicates what explicit hosts should be
allowed to embed iframe. See also %HTML.SafeIframeRegexp,
it has precedence over this config. Here are some example values:
</p>
<ul>
<li><code>www.youtube.com</code> - Allow YouTube videos</li>
<li><code>maps.google.com</code> - Allow Embedding a Google map</li>
</ul>
--# vim: et sw=4 sts=4

View File

@@ -142,12 +142,11 @@ class HTMLPurifier_ContentSets
if ($return !== false) {
return $return;
}
// error-out
trigger_error(
throw new Exception(
'Could not determine which ChildDef class to instantiate',
E_USER_ERROR
);
return false;
}
/**

View File

@@ -24,11 +24,7 @@ class HTMLPurifier_Context
public function register($name, &$ref)
{
if (array_key_exists($name, $this->_storage)) {
trigger_error(
"Name $name produces collision, cannot re-register",
E_USER_ERROR
);
return;
throw new Exception("Name $name produces collision, cannot re-register");
}
$this->_storage[$name] =& $ref;
}
@@ -43,10 +39,7 @@ class HTMLPurifier_Context
{
if (!array_key_exists($name, $this->_storage)) {
if (!$ignore_error) {
trigger_error(
"Attempted to retrieve non-existent variable $name",
E_USER_ERROR
);
throw new Exception("Attempted to retrieve non-existent variable $name");
}
$var = null; // so we can return by reference
return $var;
@@ -61,11 +54,7 @@ class HTMLPurifier_Context
public function destroy($name)
{
if (!array_key_exists($name, $this->_storage)) {
trigger_error(
"Attempted to destroy non-existent variable $name",
E_USER_ERROR
);
return;
throw new Exception("Attempted to destroy non-existent variable $name");
}
unset($this->_storage[$name]);
}

View File

@@ -112,6 +112,7 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
}
unlink($dir . '/' . $filename);
}
closedir($dh);
return true;
}
@@ -138,10 +139,12 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
continue;
}
$key = substr($filename, 0, strlen($filename) - 4);
if ($this->isOld($key, $config)) {
unlink($dir . '/' . $filename);
$file = $dir . '/' . $filename;
if ($this->isOld($key, $config) && file_exists($file)) {
unlink($file);
}
}
closedir($dh);
return true;
}
@@ -198,11 +201,8 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
if ($result !== false) {
// set permissions of the new file (no execute)
$chmod = $config->get('Cache.SerializerPermissions');
if ($chmod === null) {
// don't do anything
} else {
$chmod = $chmod & 0666;
chmod($file, $chmod);
if ($chmod !== null) {
chmod($file, $chmod & 0666);
}
}
return $result;
@@ -217,6 +217,16 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
{
$directory = $this->generateDirectoryPath($config);
$chmod = $config->get('Cache.SerializerPermissions');
if ($chmod === null) {
if (!@mkdir($directory) && !is_dir($directory)) {
trigger_error(
'Could not create directory ' . $directory . '',
E_USER_WARNING
);
return false;
}
return true;
}
if (!is_dir($directory)) {
$base = $this->generateBaseDirectoryPath($config);
if (!is_dir($base)) {
@@ -229,25 +239,14 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} elseif (!$this->_testPermissions($base, $chmod)) {
return false;
}
if ($chmod === null) {
if (!@mkdir($directory, $chmod) && !is_dir($directory)) {
trigger_error(
'Base directory ' . $base . ' does not exist,
please create or change using %Cache.SerializerPath',
'Could not create directory ' . $directory . '',
E_USER_WARNING
);
return false;
}
if ($chmod !== null) {
mkdir($directory, $chmod);
} else {
mkdir($directory);
}
if (!$this->_testPermissions($directory, $chmod)) {
trigger_error(
'Base directory ' . $base . ' does not exist,
please create or change using %Cache.SerializerPath',
E_USER_WARNING
);
return false;
}
} elseif (!$this->_testPermissions($directory, $chmod)) {
@@ -289,13 +288,14 @@ class HTMLPurifier_DefinitionCache_Serializer extends HTMLPurifier_DefinitionCac
} elseif (filegroup($dir) === posix_getgid()) {
$chmod = $chmod | 0070;
} else {
// PHP's probably running as nobody, so we'll
// need to give global permissions
$chmod = $chmod | 0777;
// PHP's probably running as nobody, it is
// not obvious how to fix this (777 is probably
// bad if you are multi-user), let the user figure it out
$chmod = null;
}
trigger_error(
'Directory ' . $dir . ' not writable, ' .
'please chmod to ' . decoct($chmod),
'Directory ' . $dir . ' not writable. ' .
($chmod === null ? '' : 'Please chmod to ' . decoct($chmod)),
E_USER_WARNING
);
} else {

View File

@@ -71,7 +71,7 @@ class HTMLPurifier_DefinitionCacheFactory
return $this->caches[$method][$type];
}
if (isset($this->implementations[$method]) &&
class_exists($class = $this->implementations[$method], false)) {
class_exists($class = $this->implementations[$method])) {
$cache = new $class($type);
} else {
if ($method != 'Serializer') {

View File

@@ -86,7 +86,7 @@ class HTMLPurifier_DoctypeRegistry
$doctype = $this->aliases[$doctype];
}
if (!isset($this->doctypes[$doctype])) {
trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR);
throw new Exception('Doctype ' . htmlspecialchars($doctype) . ' does not exist');
$anon = new HTMLPurifier_Doctype($doctype);
return $anon;
}

View File

@@ -176,7 +176,7 @@ class HTMLPurifier_ElementDef
if (!empty($def->content_model)) {
$this->content_model =
str_replace("#SUPER", $this->content_model, $def->content_model);
str_replace("#SUPER", (string)$this->content_model, $def->content_model);
$this->child = false;
}
if (!empty($def->content_model_type)) {

View File

@@ -12,7 +12,7 @@ class HTMLPurifier_Encoder
*/
private function __construct()
{
trigger_error('Cannot instantiate encoder, call methods statically', E_USER_ERROR);
throw new Exception('Cannot instantiate encoder, call methods statically');
}
/**
@@ -101,6 +101,14 @@ class HTMLPurifier_Encoder
* It will parse according to UTF-8 and return a valid UTF8 string, with
* non-SGML codepoints excluded.
*
* Specifically, it will permit:
* \x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}
* Source: https://www.w3.org/TR/REC-xml/#NT-Char
* Arguably this function should be modernized to the HTML5 set
* of allowed characters:
* https://www.w3.org/TR/html5/syntax.html#preprocessing-the-input-stream
* which simultaneously expand and restrict the set of allowed characters.
*
* @param string $str The string to clean
* @param bool $force_php
* @return string
@@ -122,15 +130,12 @@ class HTMLPurifier_Encoder
* function that needs to be able to understand UTF-8 characters.
* As of right now, only smart lossless character encoding converters
* would need that, and I'm probably not going to implement them.
* Once again, PHP 6 should solve all our problems.
*/
public static function cleanUTF8($str, $force_php = false)
{
// UTF-8 validity is checked since PHP 4.3.5
// This is an optimization: if the string is already valid UTF-8, no
// need to do PHP stuff. 99% of the time, this will be the case.
// The regexp matches the XML char production, as well as well as excluding
// non-SGML codepoints U+007F to U+009F
if (preg_match(
'/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du',
$str
@@ -154,7 +159,7 @@ class HTMLPurifier_Encoder
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$in = ord($str{$i});
$in = ord($str[$i]);
$char .= $str[$i]; // append byte to char
if (0 == $mState) {
// When mState is zero we expect either a US-ASCII character
@@ -255,6 +260,7 @@ class HTMLPurifier_Encoder
// 7F-9F is not strictly prohibited by XML,
// but it is non-SGML, and thus we don't allow it
(0xA0 <= $mUcs4 && 0xD7FF >= $mUcs4) ||
(0xE000 <= $mUcs4 && 0xFFFD >= $mUcs4) ||
(0x10000 <= $mUcs4 && 0x10FFFF >= $mUcs4)
)
) {
@@ -384,7 +390,7 @@ class HTMLPurifier_Encoder
$str = self::unsafeIconv($encoding, 'utf-8//IGNORE', $str);
if ($str === false) {
// $encoding is not a valid encoding
trigger_error('Invalid encoding ' . $encoding, E_USER_ERROR);
throw new Exception('Invalid encoding ' . $encoding);
return '';
}
// If the string is bjorked by Shift_JIS or a similar encoding
@@ -392,18 +398,17 @@ class HTMLPurifier_Encoder
// characters to their true byte-wise ASCII/UTF-8 equivalents.
$str = strtr($str, self::testEncodingSupportsASCII($encoding));
return $str;
} elseif ($encoding === 'iso-8859-1') {
$str = utf8_encode($str);
} elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) {
$str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1');
return $str;
}
$bug = HTMLPurifier_Encoder::testIconvTruncateBug();
if ($bug == self::ICONV_OK) {
trigger_error('Encoding not supported, please install iconv', E_USER_ERROR);
throw new Exception('Encoding not supported, please install iconv');
} else {
trigger_error(
throw new Exception(
'You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 ' .
'and http://sourceware.org/bugzilla/show_bug.cgi?id=13541',
E_USER_ERROR
'and http://sourceware.org/bugzilla/show_bug.cgi?id=13541'
);
}
}
@@ -444,11 +449,11 @@ class HTMLPurifier_Encoder
// Normal stuff
$str = self::iconv('utf-8', $encoding . '//IGNORE', $str);
return $str;
} elseif ($encoding === 'iso-8859-1') {
$str = utf8_decode($str);
} elseif ($encoding === 'iso-8859-1' && function_exists('mb_convert_encoding')) {
$str = mb_convert_encoding($str, 'ISO-8859-1', 'UTF-8');
return $str;
}
trigger_error('Encoding not supported', E_USER_ERROR);
throw new Exception('Encoding not supported');
// You might be tempted to assume that the ASCII representation
// might be OK, however, this is *not* universally true over all
// encodings. So we take the conservative route here, rather
@@ -539,10 +544,9 @@ class HTMLPurifier_Encoder
} elseif (($c = strlen($r)) < 9000) {
$code = self::ICONV_TRUNCATES;
} elseif ($c > 9000) {
trigger_error(
throw new Exception(
'Your copy of iconv is extremely buggy. Please notify HTML Purifier maintainers: ' .
'include your iconv version as per phpversion()',
E_USER_ERROR
'include your iconv version as per phpversion()'
);
} else {
$code = self::ICONV_OK;

View File

@@ -5,7 +5,7 @@
// $config or $context to the callback functions.
/**
* Handles referencing and derefencing character entities
* Handles referencing and dereferencing character entities
*/
class HTMLPurifier_EntityParser
{
@@ -16,6 +16,138 @@ class HTMLPurifier_EntityParser
*/
protected $_entity_lookup;
/**
* Callback regex string for entities in text.
* @type string
*/
protected $_textEntitiesRegex;
/**
* Callback regex string for entities in attributes.
* @type string
*/
protected $_attrEntitiesRegex;
/**
* Tests if the beginning of a string is a semi-optional regex
*/
protected $_semiOptionalPrefixRegex;
public function __construct() {
// From
// http://stackoverflow.com/questions/15532252/why-is-reg-being-rendered-as-without-the-bounding-semicolon
$semi_optional = "quot|QUOT|lt|LT|gt|GT|amp|AMP|AElig|Aacute|Acirc|Agrave|Aring|Atilde|Auml|COPY|Ccedil|ETH|Eacute|Ecirc|Egrave|Euml|Iacute|Icirc|Igrave|Iuml|Ntilde|Oacute|Ocirc|Ograve|Oslash|Otilde|Ouml|REG|THORN|Uacute|Ucirc|Ugrave|Uuml|Yacute|aacute|acirc|acute|aelig|agrave|aring|atilde|auml|brvbar|ccedil|cedil|cent|copy|curren|deg|divide|eacute|ecirc|egrave|eth|euml|frac12|frac14|frac34|iacute|icirc|iexcl|igrave|iquest|iuml|laquo|macr|micro|middot|nbsp|not|ntilde|oacute|ocirc|ograve|ordf|ordm|oslash|otilde|ouml|para|plusmn|pound|raquo|reg|sect|shy|sup1|sup2|sup3|szlig|thorn|times|uacute|ucirc|ugrave|uml|uuml|yacute|yen|yuml";
// NB: three empty captures to put the fourth match in the right
// place
$this->_semiOptionalPrefixRegex = "/&()()()($semi_optional)/";
$this->_textEntitiesRegex =
'/&(?:'.
// hex
'[#]x([a-fA-F0-9]+);?|'.
// dec
'[#]0*(\d+);?|'.
// string (mandatory semicolon)
// NB: order matters: match semicolon preferentially
'([A-Za-z_:][A-Za-z0-9.\-_:]*);|'.
// string (optional semicolon)
"($semi_optional)".
')/';
$this->_attrEntitiesRegex =
'/&(?:'.
// hex
'[#]x([a-fA-F0-9]+);?|'.
// dec
'[#]0*(\d+);?|'.
// string (mandatory semicolon)
// NB: order matters: match semicolon preferentially
'([A-Za-z_:][A-Za-z0-9.\-_:]*);|'.
// string (optional semicolon)
// don't match if trailing is equals or alphanumeric (URL
// like)
"($semi_optional)(?![=;A-Za-z0-9])".
')/';
}
/**
* Substitute entities with the parsed equivalents. Use this on
* textual data in an HTML document (as opposed to attributes.)
*
* @param string $string String to have entities parsed.
* @return string Parsed string.
*/
public function substituteTextEntities($string)
{
return preg_replace_callback(
$this->_textEntitiesRegex,
array($this, 'entityCallback'),
$string
);
}
/**
* Substitute entities with the parsed equivalents. Use this on
* attribute contents in documents.
*
* @param string $string String to have entities parsed.
* @return string Parsed string.
*/
public function substituteAttrEntities($string)
{
return preg_replace_callback(
$this->_attrEntitiesRegex,
array($this, 'entityCallback'),
$string
);
}
/**
* Callback function for substituteNonSpecialEntities() that does the work.
*
* @param array $matches PCRE matches array, with 0 the entire match, and
* either index 1, 2 or 3 set with a hex value, dec value,
* or string (respectively).
* @return string Replacement string.
*/
protected function entityCallback($matches)
{
$entity = $matches[0];
$hex_part = isset($matches[1]) ? $matches[1] : null;
$dec_part = isset($matches[2]) ? $matches[2] : null;
$named_part = empty($matches[3]) ? (empty($matches[4]) ? "" : $matches[4]) : $matches[3];
if ($hex_part !== NULL && $hex_part !== "") {
return HTMLPurifier_Encoder::unichr(hexdec($hex_part));
} elseif ($dec_part !== NULL && $dec_part !== "") {
return HTMLPurifier_Encoder::unichr((int) $dec_part);
} else {
if (!$this->_entity_lookup) {
$this->_entity_lookup = HTMLPurifier_EntityLookup::instance();
}
if (isset($this->_entity_lookup->table[$named_part])) {
return $this->_entity_lookup->table[$named_part];
} else {
// exact match didn't match anything, so test if
// any of the semicolon optional match the prefix.
// Test that this is an EXACT match is important to
// prevent infinite loop
if (!empty($matches[3])) {
return preg_replace_callback(
$this->_semiOptionalPrefixRegex,
array($this, 'entityCallback'),
$entity
);
}
return $entity;
}
}
}
// LEGACY CODE BELOW
/**
* Callback regex string for parsing entities.
* @type string
@@ -144,7 +276,7 @@ class HTMLPurifier_EntityParser
$entity;
} else {
return isset($this->_special_ent2dec[$matches[3]]) ?
$this->_special_ent2dec[$matches[3]] :
$this->_special_dec2str[$this->_special_ent2dec[$matches[3]]] :
$entity;
}
}

View File

@@ -4,7 +4,7 @@
* Represents a pre or post processing filter on HTML Purifier's output
*
* Sometimes, a little ad-hoc fixing of HTML has to be done before
* it gets sent through HTML Purifier: you can use filters to acheive
* it gets sent through HTML Purifier: you can use filters to achieve
* this effect. For instance, YouTube videos can be preserved using
* this manner. You could have used a decorator for this task, but
* PHP's support for them is not terribly robust, so we're going

View File

@@ -54,6 +54,11 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
*/
private $_enum_attrdef;
/**
* @type HTMLPurifier_AttrDef_Enum
*/
private $_universal_attrdef;
public function __construct()
{
$this->_tidy = new csstidy();
@@ -70,6 +75,13 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
'focus'
)
);
$this->_universal_attrdef = new HTMLPurifier_AttrDef_Enum(
array(
'initial',
'inherit',
'unset',
)
);
}
/**
@@ -95,7 +107,10 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
if ($tidy !== null) {
$this->_tidy = $tidy;
}
$html = preg_replace_callback('#<style(?:\s.*)?>(.+)</style>#isU', array($this, 'styleCallback'), $html);
// NB: this must be NON-greedy because if we have
// <style>foo</style> <style>bar</style>
// we must not grab foo</style> <style>bar
$html = preg_replace_callback('#<style(?:\s.*)?>(.*)<\/style>#isU', array($this, 'styleCallback'), $html);
$style_blocks = $this->_styleMatches;
$this->_styleMatches = array(); // reset
$context->register('StyleBlocks', $style_blocks); // $context must not be reused
@@ -143,175 +158,184 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
foreach ($this->_tidy->css as $k => $decls) {
// $decls are all CSS declarations inside an @ selector
$new_decls = array();
foreach ($decls as $selector => $style) {
$selector = trim($selector);
if ($selector === '') {
continue;
} // should not happen
// Parse the selector
// Here is the relevant part of the CSS grammar:
//
// ruleset
// : selector [ ',' S* selector ]* '{' ...
// selector
// : simple_selector [ combinator selector | S+ [ combinator? selector ]? ]?
// combinator
// : '+' S*
// : '>' S*
// simple_selector
// : element_name [ HASH | class | attrib | pseudo ]*
// | [ HASH | class | attrib | pseudo ]+
// element_name
// : IDENT | '*'
// ;
// class
// : '.' IDENT
// ;
// attrib
// : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*
// [ IDENT | STRING ] S* ]? ']'
// ;
// pseudo
// : ':' [ IDENT | FUNCTION S* [IDENT S*]? ')' ]
// ;
//
// For reference, here are the relevant tokens:
//
// HASH #{name}
// IDENT {ident}
// INCLUDES ==
// DASHMATCH |=
// STRING {string}
// FUNCTION {ident}\(
//
// And the lexical scanner tokens
//
// name {nmchar}+
// nmchar [_a-z0-9-]|{nonascii}|{escape}
// nonascii [\240-\377]
// escape {unicode}|\\[^\r\n\f0-9a-f]
// unicode \\{h}}{1,6}(\r\n|[ \t\r\n\f])?
// ident -?{nmstart}{nmchar*}
// nmstart [_a-z]|{nonascii}|{escape}
// string {string1}|{string2}
// string1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\"
// string2 \'([^\n\r\f\\"]|\\{nl}|{escape})*\'
//
// We'll implement a subset (in order to reduce attack
// surface); in particular:
//
// - No Unicode support
// - No escapes support
// - No string support (by proxy no attrib support)
// - element_name is matched against allowed
// elements (some people might find this
// annoying...)
// - Pseudo-elements one of :first-child, :link,
// :visited, :active, :hover, :focus
if (is_array($decls)) {
foreach ($decls as $selector => $style) {
$selector = trim($selector);
if ($selector === '') {
continue;
} // should not happen
// Parse the selector
// Here is the relevant part of the CSS grammar:
//
// ruleset
// : selector [ ',' S* selector ]* '{' ...
// selector
// : simple_selector [ combinator selector | S+ [ combinator? selector ]? ]?
// combinator
// : '+' S*
// : '>' S*
// simple_selector
// : element_name [ HASH | class | attrib | pseudo ]*
// | [ HASH | class | attrib | pseudo ]+
// element_name
// : IDENT | '*'
// ;
// class
// : '.' IDENT
// ;
// attrib
// : '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*
// [ IDENT | STRING ] S* ]? ']'
// ;
// pseudo
// : ':' [ IDENT | FUNCTION S* [IDENT S*]? ')' ]
// ;
//
// For reference, here are the relevant tokens:
//
// HASH #{name}
// IDENT {ident}
// INCLUDES ==
// DASHMATCH |=
// STRING {string}
// FUNCTION {ident}\(
//
// And the lexical scanner tokens
//
// name {nmchar}+
// nmchar [_a-z0-9-]|{nonascii}|{escape}
// nonascii [\240-\377]
// escape {unicode}|\\[^\r\n\f0-9a-f]
// unicode \\{h}}{1,6}(\r\n|[ \t\r\n\f])?
// ident -?{nmstart}{nmchar*}
// nmstart [_a-z]|{nonascii}|{escape}
// string {string1}|{string2}
// string1 \"([^\n\r\f\\"]|\\{nl}|{escape})*\"
// string2 \'([^\n\r\f\\"]|\\{nl}|{escape})*\'
//
// We'll implement a subset (in order to reduce attack
// surface); in particular:
//
// - No Unicode support
// - No escapes support
// - No string support (by proxy no attrib support)
// - element_name is matched against allowed
// elements (some people might find this
// annoying...)
// - Pseudo-elements one of :first-child, :link,
// :visited, :active, :hover, :focus
// handle ruleset
$selectors = array_map('trim', explode(',', $selector));
$new_selectors = array();
foreach ($selectors as $sel) {
// split on +, > and spaces
$basic_selectors = preg_split('/\s*([+> ])\s*/', $sel, -1, PREG_SPLIT_DELIM_CAPTURE);
// even indices are chunks, odd indices are
// delimiters
$nsel = null;
$delim = null; // guaranteed to be non-null after
// two loop iterations
for ($i = 0, $c = count($basic_selectors); $i < $c; $i++) {
$x = $basic_selectors[$i];
if ($i % 2) {
// delimiter
if ($x === ' ') {
$delim = ' ';
} else {
$delim = ' ' . $x . ' ';
}
} else {
// simple selector
$components = preg_split('/([#.:])/', $x, -1, PREG_SPLIT_DELIM_CAPTURE);
$sdelim = null;
$nx = null;
for ($j = 0, $cc = count($components); $j < $cc; $j++) {
$y = $components[$j];
if ($j === 0) {
if ($y === '*' || isset($html_definition->info[$y = strtolower($y)])) {
$nx = $y;
} else {
// $nx stays null; this matters
// if we don't manage to find
// any valid selector content,
// in which case we ignore the
// outer $delim
}
} elseif ($j % 2) {
// set delimiter
$sdelim = $y;
// handle ruleset
$selectors = array_map('trim', explode(',', $selector));
$new_selectors = array();
foreach ($selectors as $sel) {
// split on +, > and spaces
$basic_selectors = preg_split('/\s*([+> ])\s*/', $sel, -1, PREG_SPLIT_DELIM_CAPTURE);
// even indices are chunks, odd indices are
// delimiters
$nsel = null;
$delim = null; // guaranteed to be non-null after
// two loop iterations
for ($i = 0, $c = count($basic_selectors); $i < $c; $i++) {
$x = $basic_selectors[$i];
if ($i % 2) {
// delimiter
if ($x === ' ') {
$delim = ' ';
} else {
$attrdef = null;
if ($sdelim === '#') {
$attrdef = $this->_id_attrdef;
} elseif ($sdelim === '.') {
$attrdef = $this->_class_attrdef;
} elseif ($sdelim === ':') {
$attrdef = $this->_enum_attrdef;
} else {
throw new HTMLPurifier_Exception('broken invariant sdelim and preg_split');
}
$r = $attrdef->validate($y, $config, $context);
if ($r !== false) {
if ($r !== true) {
$y = $r;
}
if ($nx === null) {
$nx = '';
}
$nx .= $sdelim . $y;
}
}
}
if ($nx !== null) {
if ($nsel === null) {
$nsel = $nx;
} else {
$nsel .= $delim . $nx;
$delim = ' ' . $x . ' ';
}
} else {
// delimiters to the left of invalid
// basic selector ignored
// simple selector
$components = preg_split('/([#.:])/', $x, -1, PREG_SPLIT_DELIM_CAPTURE);
$sdelim = null;
$nx = null;
for ($j = 0, $cc = count($components); $j < $cc; $j++) {
$y = $components[$j];
if ($j === 0) {
if ($y === '*' || isset($html_definition->info[$y = strtolower($y)])) {
$nx = $y;
} else {
// $nx stays null; this matters
// if we don't manage to find
// any valid selector content,
// in which case we ignore the
// outer $delim
}
} elseif ($j % 2) {
// set delimiter
$sdelim = $y;
} else {
$attrdef = null;
if ($sdelim === '#') {
$attrdef = $this->_id_attrdef;
} elseif ($sdelim === '.') {
$attrdef = $this->_class_attrdef;
} elseif ($sdelim === ':') {
$attrdef = $this->_enum_attrdef;
} else {
throw new HTMLPurifier_Exception('broken invariant sdelim and preg_split');
}
$r = $attrdef->validate($y, $config, $context);
if ($r !== false) {
if ($r !== true) {
$y = $r;
}
if ($nx === null) {
$nx = '';
}
$nx .= $sdelim . $y;
}
}
}
if ($nx !== null) {
if ($nsel === null) {
$nsel = $nx;
} else {
$nsel .= $delim . $nx;
}
} else {
// delimiters to the left of invalid
// basic selector ignored
}
}
}
if ($nsel !== null) {
if (!empty($scopes)) {
foreach ($scopes as $s) {
$new_selectors[] = "$s $nsel";
}
} else {
$new_selectors[] = $nsel;
}
}
}
if ($nsel !== null) {
if (!empty($scopes)) {
foreach ($scopes as $s) {
$new_selectors[] = "$s $nsel";
}
} else {
$new_selectors[] = $nsel;
}
}
}
if (empty($new_selectors)) {
continue;
}
$selector = implode(', ', $new_selectors);
foreach ($style as $name => $value) {
if (!isset($css_definition->info[$name])) {
unset($style[$name]);
if (empty($new_selectors)) {
continue;
}
$def = $css_definition->info[$name];
$ret = $def->validate($value, $config, $context);
if ($ret === false) {
unset($style[$name]);
} else {
$style[$name] = $ret;
$selector = implode(', ', $new_selectors);
foreach ($style as $name => $value) {
if (!isset($css_definition->info[$name])) {
unset($style[$name]);
continue;
}
$uni_ret = $this->_universal_attrdef->validate($value, $config, $context);
if ($uni_ret !== false) {
$style[$name] = $uni_ret;
continue;
}
$def = $css_definition->info[$name];
$ret = $def->validate($value, $config, $context);
if ($ret === false) {
unset($style[$name]);
} else {
$style[$name] = $ret;
}
}
$new_decls[$selector] = $style;
}
$new_decls[$selector] = $style;
} else {
continue;
}
$new_css[$k] = $new_decls;
}

View File

@@ -19,7 +19,7 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
$pre_regex = '#<object[^>]+>.+?' .
'(?:http:)?//www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?</object>#s';
$pre_replace = '<span class="youtube-embed">\1</span>';
return preg_replace($pre_regex, $pre_replace, $html);
return preg_replace($pre_regex, $pre_replace, (string)$html);
}
/**
@@ -31,7 +31,7 @@ class HTMLPurifier_Filter_YouTube extends HTMLPurifier_Filter
public function postFilter($html, $config, $context)
{
$post_regex = '#<span class="youtube-embed">((?:v|cp)/[A-Za-z0-9\-_=]+)</span>#';
return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html);
return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), (string)$html);
}
/**

View File

@@ -146,7 +146,7 @@ class HTMLPurifier_Generator
$attr = $this->generateAttributes($token->attr, $token->name);
if ($this->_flashCompat) {
if ($token->name == "object") {
$flash = new stdclass();
$flash = new stdClass();
$flash->attr = $token->attr;
$flash->param = array();
$this->_flashStack[] = $flash;
@@ -244,7 +244,7 @@ class HTMLPurifier_Generator
// whitespace (in fact, most don't, at least for attributes
// like alt, but an extra space at the end is barely
// noticeable). Still, we have a configuration knob for
// this, since this transformation is not necesary if you
// this, since this transformation is not necessary if you
// don't process user input with innerHTML or you don't plan
// on supporting Internet Explorer.
if ($this->_innerHTMLFix) {

View File

@@ -264,9 +264,8 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
if (isset($this->info_content_sets['Block'][$block_wrapper])) {
$this->info_block_wrapper = $block_wrapper;
} else {
trigger_error(
'Cannot use non-block element as block wrapper',
E_USER_ERROR
throw new Exception(
'Cannot use non-block element as block wrapper'
);
}
@@ -276,11 +275,7 @@ class HTMLPurifier_HTMLDefinition extends HTMLPurifier_Definition
$this->info_parent = $parent;
$this->info_parent_def = $def;
} else {
trigger_error(
'Cannot use unrecognized element as parent',
E_USER_ERROR
);
$this->info_parent_def = $this->manager->getElement($this->info_parent, true);
throw new Exception('Cannot use unrecognized element as parent');
}
// support template text

View File

@@ -132,9 +132,9 @@ class HTMLPurifier_HTMLModule
* @param string $element Name of element to add
* @param string|bool $type What content set should element be registered to?
* Set as false to skip this step.
* @param string $contents Allowed children in form of:
* @param string|HTMLPurifier_ChildDef $contents Allowed children in form of:
* "$content_model_type: $content_model"
* @param array $attr_includes What attribute collections to register to
* @param array|string $attr_includes What attribute collections to register to
* element?
* @param array $attr What unique attributes does the element define?
* @see HTMLPurifier_ElementDef:: for in-depth descriptions of these parameters.
@@ -257,8 +257,9 @@ class HTMLPurifier_HTMLModule
*/
public function makeLookup($list)
{
$args = func_get_args();
if (is_string($list)) {
$list = func_get_args();
$list = $args;
}
$ret = array();
foreach ($list as $value) {

View File

@@ -17,6 +17,7 @@ class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule
'class' => 'Class',
'id' => 'ID',
'title' => 'CDATA',
'contenteditable' => 'ContentEditable',
),
'Lang' => array(),
'I18N' => array(

View File

@@ -28,7 +28,7 @@ class HTMLPurifier_HTMLModule_Edit extends HTMLPurifier_HTMLModule
// HTML 4.01 specifies that ins/del must not contain block
// elements when used in an inline context, chameleon is
// a complicated workaround to acheive this effect
// a complicated workaround to achieve this effect
// Inline context ! Block context (exclamation mark is
// separator, see getChildDef for parsing)

View File

@@ -28,6 +28,10 @@ class HTMLPurifier_HTMLModule_Forms extends HTMLPurifier_HTMLModule
*/
public function setup($config)
{
if ($config->get('HTML.Forms')) {
$this->safe = true;
}
$form = $this->addElement(
'form',
'Form',

View File

@@ -28,22 +28,28 @@ class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
if ($config->get('HTML.SafeIframe')) {
$this->safe = true;
}
$attrs = array(
'src' => 'URI#embedded',
'width' => 'Length',
'height' => 'Length',
'name' => 'ID',
'scrolling' => 'Enum#yes,no,auto',
'frameborder' => 'Enum#0,1',
'longdesc' => 'URI',
'marginheight' => 'Pixels',
'marginwidth' => 'Pixels',
);
if ($config->get('HTML.Trusted')) {
$attrs['allowfullscreen'] = 'Bool#allowfullscreen';
}
$this->addElement(
'iframe',
'Inline',
'Flow',
'Common',
array(
'src' => 'URI#embedded',
'width' => 'Length',
'height' => 'Length',
'name' => 'ID',
'scrolling' => 'Enum#yes,no,auto',
'frameborder' => 'Enum#0,1',
'longdesc' => 'URI',
'marginheight' => 'Pixels',
'marginwidth' => 'Pixels',
)
$attrs
);
}
}

View File

@@ -2,7 +2,7 @@
/**
* XHTML 1.1 Ruby Annotation Module, defines elements that indicate
* short runs of text alongside base text for annotation or pronounciation.
* short runs of text alongside base text for annotation or pronunciation.
*/
class HTMLPurifier_HTMLModule_Ruby extends HTMLPurifier_HTMLModule
{

Some files were not shown because too many files have changed in this diff Show More