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

Compare commits

...

100 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
184 changed files with 1529 additions and 940 deletions

32
.gitattributes vendored
View File

@@ -1,13 +1,25 @@
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/.travis.yml 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

View File

@@ -1,14 +0,0 @@
language: php
php:
- '5.4'
- '5.5'
- '5.6'
- '7.0'
- '7.1'
- '7.2'
- '7.3'
before_script:
- git clone --depth=50 https://github.com/ezyang/simpletest.git
- cp test-settings.travis.php test-settings.php
script:
- php tests/index.php

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.11.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.

View File

@@ -99,7 +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:
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

111
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,58 @@ 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>
@@ -387,7 +482,7 @@ real release we decided to skip this version number.
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.
@@ -427,7 +522,7 @@ real release we decided to skip this version number.
! %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.
@@ -478,7 +573,7 @@ real release we decided to skip this version number.
. 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="">)
@@ -628,7 +723,7 @@ real release we decided to skip this version number.
# 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
@@ -674,7 +769,7 @@ real release we decided to skip this version number.
. 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
@@ -740,7 +835,7 @@ real release we decided to skip this version number.
- 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)
@@ -786,7 +881,7 @@ real release we decided to skip this version number.
! 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.
@@ -837,7 +932,7 @@ real release we decided to skip this version number.
. 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,4 +1,4 @@
HTML Purifier [![Build Status](https://secure.travis-ci.org/ezyang/htmlpurifier.svg?branch=master)](http://travis-ci.org/ezyang/htmlpurifier)
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

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.11.0
4.18.0

View File

@@ -1,7 +0,0 @@
HTML Purifier 4.11.x is a maintenance release, collecting a year
and a half of accumulated bug fixes. Most notable fixes are
compatibility with PHP 7.3, and case-sensitive matching for
the SafeScripting whitelist. There are a number small feature
enhancements, including an expanded supported color list,
initial and inherit support for {min-,max-,}{width,height}
and multidimensional array support for purifyArray.

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

@@ -13,13 +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": {
"simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
"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,8 +5,8 @@
<line>162</line>
</file>
<file name="HTMLPurifier/Lexer.php">
<line>85</line>
<line>326</line>
<line>90</line>
<line>315</line>
</file>
<file name="HTMLPurifier/Lexer/DirectLex.php">
<line>67</line>
@@ -19,37 +19,37 @@
</directive>
<directive id="CSS.MaxImgLength">
<file name="HTMLPurifier/CSSDefinition.php">
<line>240</line>
<line>253</line>
</file>
</directive>
<directive id="CSS.Proprietary">
<file name="HTMLPurifier/CSSDefinition.php">
<line>365</line>
<line>397</line>
</file>
</directive>
<directive id="CSS.AllowTricky">
<file name="HTMLPurifier/CSSDefinition.php">
<line>369</line>
<line>401</line>
</file>
</directive>
<directive id="CSS.Trusted">
<file name="HTMLPurifier/CSSDefinition.php">
<line>373</line>
<line>405</line>
</file>
</directive>
<directive id="CSS.AllowImportant">
<file name="HTMLPurifier/CSSDefinition.php">
<line>377</line>
<line>409</line>
</file>
</directive>
<directive id="CSS.AllowedProperties">
<file name="HTMLPurifier/CSSDefinition.php">
<line>506</line>
<line>538</line>
</file>
</directive>
<directive id="CSS.ForbiddenProperties">
<file name="HTMLPurifier/CSSDefinition.php">
<line>522</line>
<line>554</line>
</file>
</directive>
<directive id="Cache.DefinitionImpl">
@@ -124,7 +124,7 @@
<line>122</line>
</file>
<file name="HTMLPurifier/Lexer.php">
<line>308</line>
<line>299</line>
</file>
</directive>
<directive id="Output.Newline">
@@ -172,8 +172,14 @@
<line>234</line>
</file>
<file name="HTMLPurifier/Lexer.php">
<line>313</line>
<line>353</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>
@@ -250,12 +256,12 @@
</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>
@@ -263,23 +269,23 @@
</directive>
<directive id="Core.LegacyEntityDecoder">
<file name="HTMLPurifier/Lexer.php">
<line>215</line>
<line>337</line>
<line>220</line>
<line>326</line>
</file>
</directive>
<directive id="Core.ConvertDocumentToFragment">
<file name="HTMLPurifier/Lexer.php">
<line>324</line>
<line>313</line>
</file>
</directive>
<directive id="Core.RemoveProcessingInstructions">
<file name="HTMLPurifier/Lexer.php">
<line>347</line>
<line>336</line>
</file>
</directive>
<directive id="Core.HiddenElements">
<file name="HTMLPurifier/Lexer.php">
<line>351</line>
<line>340</line>
</file>
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
<line>36</line>
@@ -287,12 +293,12 @@
</directive>
<directive id="Core.AggressivelyRemoveScript">
<file name="HTMLPurifier/Lexer.php">
<line>352</line>
<line>341</line>
</file>
</directive>
<directive id="Core.RemoveScriptContents">
<file name="HTMLPurifier/Lexer.php">
<line>353</line>
<line>342</line>
</file>
<file name="HTMLPurifier/Strategy/RemoveForeignElements.php">
<line>35</line>
@@ -354,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">
@@ -405,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>109</line>
<line>103</line>
</file>
</directive>
<directive id="Attr.DefaultTextDir">
@@ -451,7 +457,7 @@
</directive>
<directive id="HTML.FlashAllowFullScreen">
<file name="HTMLPurifier/AttrTransform/SafeParam.php">
<line>53</line>
<line>58</line>
</file>
</directive>
<directive id="Cache.SerializerPath">
@@ -467,17 +473,22 @@
</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>125</line>
<line>137</line>
</file>
</directive>
<directive id="Filter.ExtractStyleBlocks.Escaping">
<file name="HTMLPurifier/Filter/ExtractStyleBlocks.php">
<line>330</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">
@@ -544,6 +555,11 @@
<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>
@@ -592,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

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

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

View File

@@ -17,6 +17,7 @@ if (function_exists('spl_autoload_register') && function_exists('spl_autoload_un
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.11.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';

View File

@@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.11.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.11.0';
public $version = '4.18.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.11.0';
const VERSION = '4.18.0';
/**
* Global configuration object.
@@ -240,6 +240,7 @@ class HTMLPurifier
public function purifyArray($array_of_html, $config = null)
{
$context_array = array();
$array = array();
foreach($array_of_html as $key=>$value){
if (is_array($value)) {
$array[$key] = $this->purifyArray($value, $config);

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';

View File

@@ -27,6 +27,13 @@ class HTMLPurifier_AttrDef_CSS extends HTMLPurifier_AttrDef
$definition = $config->getCSSDefinition();
$allow_duplicates = $config->get("CSS.AllowDuplicates");
$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
@@ -96,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

@@ -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;
}
// 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)?";
@@ -106,7 +100,7 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// 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);

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

@@ -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', '>=')) {
} else {
// 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);
}
}
}
}
}

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,41 +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', 'initial', 'inherit'))
)
new HTMLPurifier_AttrDef_Enum(['auto'])
]
);
$trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit'))
)
]
);
$trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite(
array(
[
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit'))
)
new HTMLPurifier_AttrDef_Enum(['none'])
]
);
$max = $config->get('CSS.MaxImgLength');
@@ -247,10 +265,10 @@ 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
@@ -262,12 +280,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
new HTMLPurifier_AttrDef_Switch(
'img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit'))
)
),
// For everyone else:
$trusted_min_wh
);
@@ -279,22 +292,46 @@ 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('none', 'initial', 'inherit'))
)
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',
@@ -308,7 +345,7 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
'700',
'800',
'900'
),
],
false
);
@@ -324,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',
@@ -347,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);
@@ -359,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')) {
@@ -406,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'] =
@@ -437,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',
@@ -456,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();
}
@@ -471,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

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;

View File

@@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.11.0';
public $version = '4.18.0';
/**
* Whether or not to automatically finalize
@@ -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();
@@ -898,8 +898,12 @@ class HTMLPurifier_Config
break;
}
}
if ($no == E_USER_ERROR) {
throw new Exception($msg . $extra);
} else {
trigger_error($msg . $extra, $no);
}
}
/**
* Returns a serialized form of the configuration object that can

View File

@@ -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;
}

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
*/

File diff suppressed because one or more lines are too long

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

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

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

@@ -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,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

@@ -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

@@ -139,8 +139,9 @@ 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);
@@ -287,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');
}
/**
@@ -159,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
@@ -390,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
@@ -398,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'
);
}
}
@@ -450,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
@@ -545,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
{
@@ -116,8 +116,8 @@ class HTMLPurifier_EntityParser
protected function entityCallback($matches)
{
$entity = $matches[0];
$hex_part = @$matches[1];
$dec_part = @$matches[2];
$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));

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',
)
);
}
/**
@@ -146,6 +158,7 @@ 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();
if (is_array($decls)) {
foreach ($decls as $selector => $style) {
$selector = trim($selector);
if ($selector === '') {
@@ -306,6 +319,11 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
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) {
@@ -316,6 +334,9 @@ class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter
}
$new_decls[$selector] = $style;
}
} else {
continue;
}
$new_css[$k] = $new_decls;
}
// remove stuff that shouldn't be used, could be reenabled

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

@@ -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,12 +28,7 @@ class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
if ($config->get('HTML.SafeIframe')) {
$this->safe = true;
}
$this->addElement(
'iframe',
'Inline',
'Flow',
'Common',
array(
$attrs = array(
'src' => 'URI#embedded',
'width' => 'Length',
'height' => 'Length',
@@ -43,7 +38,18 @@ class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
'longdesc' => 'URI',
'marginheight' => 'Pixels',
'marginwidth' => 'Pixels',
)
);
if ($config->get('HTML.Trusted')) {
$attrs['allowfullscreen'] = 'Bool#allowfullscreen';
}
$this->addElement(
'iframe',
'Inline',
'Flow',
'Common',
$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
{

View File

@@ -112,9 +112,8 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
return;
}
if (!isset($this->fixesForLevel[$this->defaultLevel])) {
trigger_error(
'Default level ' . $this->defaultLevel . ' does not exist',
E_USER_ERROR
throw new Exception(
'Default level ' . $this->defaultLevel . ' does not exist'
);
return;
}
@@ -146,10 +145,7 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
$type = "info_$type";
$e = $this;
}
// PHP does some weird parsing when I do
// $e->$type[$attr], so I have to assign a ref.
$f =& $e->$type;
$f[$attr] = $fix;
$e->{$type}[$attr] = $fix;
break;
case 'tag_transform':
$this->info_tag_transform[$params['element']] = $fix;
@@ -165,8 +161,7 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
$e->$type = $fix;
break;
default:
trigger_error("Fix type $type not supported", E_USER_ERROR);
break;
throw new Exception("Fix type $type not supported");
}
}
}
@@ -224,6 +219,7 @@ class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
*/
public function makeFixes()
{
return array();
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* Name is deprecated, but allowed in strict doctypes, so onl
* Name is deprecated, but allowed in strict doctypes, so only
*/
class HTMLPurifier_HTMLModule_Tidy_Name extends HTMLPurifier_HTMLModule_Tidy
{

View File

@@ -96,6 +96,7 @@ class HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4 extends HTMLPurifier_HTMLModule
// @bgcolor for table, tr, td, th ---------------------------------
$r['table@bgcolor'] =
$r['tr@bgcolor'] =
$r['td@bgcolor'] =
$r['th@bgcolor'] =
new HTMLPurifier_AttrTransform_BgColor();
@@ -167,9 +168,11 @@ class HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4 extends HTMLPurifier_HTMLModule
// @vspace for img ------------------------------------------------
$r['img@vspace'] = new HTMLPurifier_AttrTransform_ImgSpace('vspace');
// @width for hr, td, th ------------------------------------------
// @width for table, hr, td, th, col ------------------------------------------
$r['table@width'] =
$r['td@width'] =
$r['th@width'] =
$r['col@width'] =
$r['hr@width'] = new HTMLPurifier_AttrTransform_Length('width');
return $r;

View File

@@ -183,11 +183,7 @@ class HTMLPurifier_HTMLModuleManager
if (!$ok) {
$module = $original_module;
if (!class_exists($module)) {
trigger_error(
$original_module . ' module does not exist',
E_USER_ERROR
);
return;
throw new Exception($original_module . ' module does not exist');
}
}
$module = new $module();

View File

@@ -40,6 +40,9 @@ class HTMLPurifier_Injector_Linkify extends HTMLPurifier_Injector
'/\\b((?:[a-z][\\w\\-]+:(?:\\/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}\\/)(?:[^\\s()<>]|\\((?:[^\\s()<>]|(?:\\([^\\s()<>]+\\)))*\\))+(?:\\((?:[^\\s()<>]|(?:\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:\'".,<>?\x{00ab}\x{00bb}\x{201c}\x{201d}\x{2018}\x{2019}]))/iu',
$token->data, -1, PREG_SPLIT_DELIM_CAPTURE);
if ($bits === false) {
return;
}
$token = array();

View File

@@ -31,6 +31,16 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In
*/
private $context;
/**
* @type SplObjectStorage
*/
private $markForDeletion;
public function __construct()
{
$this->markForDeletion = new SplObjectStorage();
}
public function prepare($config, $context)
{
$this->attrValidator = new HTMLPurifier_AttrValidator();
@@ -64,7 +74,7 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In
if ($current instanceof HTMLPurifier_Token_End && $current->name === 'span') {
// Mark closing span tag for deletion
$current->markForDeletion = true;
$this->markForDeletion->attach($current);
// Delete open span tag
$token = false;
}
@@ -75,7 +85,8 @@ class HTMLPurifier_Injector_RemoveSpansWithoutAttributes extends HTMLPurifier_In
*/
public function handleEnd(&$token)
{
if ($token->markForDeletion) {
if ($this->markForDeletion->contains($token)) {
$this->markForDeletion->detach($token);
$token = false;
}
}

View File

@@ -1,9 +0,0 @@
<?php
// private class for unit testing
class HTMLPurifier_Language_en_x_test extends HTMLPurifier_Language
{
}
// vim: et sw=4 sts=4

View File

@@ -1,13 +0,0 @@
<?php
// private language message file for unit testing purposes
$fallback = 'en';
$messages = array(
'HTMLPurifier' => 'HTML Purifier X'
);
$errorNames = array();
// vim: et sw=4 sts=4

View File

@@ -1,14 +0,0 @@
<?php
// private language message file for unit testing purposes
// this language file has no class associated with it
$fallback = 'en';
$messages = array(
'HTMLPurifier' => 'HTML Purifier XNone'
);
$errorNames = array();
// vim: et sw=4 sts=4

View File

@@ -109,7 +109,7 @@ class HTMLPurifier_LanguageFactory
} else {
$class = 'HTMLPurifier_Language_' . $pcode;
$file = $this->dir . '/Language/classes/' . $code . '.php';
if (file_exists($file) || class_exists($class, false)) {
if (file_exists($file) || class_exists($class)) {
$lang = new $class($config, $context);
} else {
// Go fallback
@@ -173,14 +173,8 @@ class HTMLPurifier_LanguageFactory
// infinite recursion guard
if (isset($languages_seen[$code])) {
trigger_error(
'Circular fallback reference in language ' .
$code,
E_USER_ERROR
);
$fallback = 'en';
throw new Exception('Circular fallback reference in language ' . $code);
}
$language_seen[$code] = true;
// load the fallback recursively
$this->loadLanguage($fallback);

View File

@@ -78,7 +78,7 @@ class HTMLPurifier_Length
if ($this->n === '0' && $this->unit === false) {
return true;
}
if (!ctype_lower($this->unit)) {
if ($this->unit === false || !ctype_lower($this->unit)) {
$this->unit = strtolower($this->unit);
}
if (!isset(HTMLPurifier_Length::$allowedUnits[$this->unit])) {

View File

@@ -48,6 +48,11 @@ class HTMLPurifier_Lexer
*/
public $tracksLineNumbers = false;
/**
* @type HTMLPurifier_EntityParser
*/
private $_entity_parser;
// -- STATIC ----------------------------------------------------------
/**
@@ -96,7 +101,7 @@ class HTMLPurifier_Lexer
break;
}
if (class_exists('DOMDocument', false) &&
if (class_exists('DOMDocument') &&
method_exists('DOMDocument', 'loadHTML') &&
!extension_loaded('domxml')
) {
@@ -233,7 +238,7 @@ class HTMLPurifier_Lexer
*/
public function tokenizeHTML($string, $config, $context)
{
trigger_error('Call to abstract class', E_USER_ERROR);
throw new Exception('Call to abstract class');
}
/**
@@ -264,20 +269,6 @@ class HTMLPurifier_Lexer
);
}
/**
* Special Internet Explorer conditional comments should be removed.
* @param string $string HTML string to process.
* @return string HTML with conditional comments removed.
*/
protected static function removeIEConditional($string)
{
return preg_replace(
'#<!--\[if [^>]+\]>.*?<!\[endif\]-->#si', // probably should generalize for all strings
'',
$string
);
}
/**
* Callback function for escapeCDATA() that does the work.
*
@@ -306,8 +297,8 @@ class HTMLPurifier_Lexer
{
// normalize newlines to \n
if ($config->get('Core.NormalizeNewlines')) {
$html = str_replace("\r\n", "\n", $html);
$html = str_replace("\r", "\n", $html);
$html = str_replace("\r\n", "\n", (string)$html);
$html = str_replace("\r", "\n", (string)$html);
}
if ($config->get('HTML.Trusted')) {
@@ -318,8 +309,6 @@ class HTMLPurifier_Lexer
// escape CDATA
$html = $this->escapeCDATA($html);
$html = $this->removeIEConditional($html);
// extract body from document if applicable
if ($config->get('Core.ConvertDocumentToFragment')) {
$e = false;

View File

@@ -52,14 +52,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
// attempt to armor stray angled brackets that cannot possibly
// form tags and thus are probably being used as emoticons
if ($config->get('Core.AggressivelyFixLt')) {
$char = '[^a-z!\/]';
$comment = "/<!--(.*?)(-->|\z)/is";
$html = preg_replace_callback($comment, array($this, 'callbackArmorCommentEntities'), $html);
do {
$old = $html;
$html = preg_replace("/<($char)/i", '&lt;\\1', $html);
} while ($html !== $old);
$html = preg_replace_callback($comment, array($this, 'callbackUndoCommentSubst'), $html); // fix comments
$html = $this->aggressivelyFixLt($html);
}
// preprocess html, essential for UTF-8
@@ -72,9 +65,17 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
if ($config->get('Core.AllowParseManyTags') && defined('LIBXML_PARSEHUGE')) {
$options |= LIBXML_PARSEHUGE;
}
if ($config->get('Core.RemoveBlanks') && defined('LIBXML_NOBLANKS')) {
$options |= LIBXML_NOBLANKS;
}
set_error_handler(array($this, 'muteErrorHandler'));
// loadHTML() fails on PHP 5.3 when second parameter is given
if ($options) {
$doc->loadHTML($html, $options);
} else {
$doc->loadHTML($html);
}
restore_error_handler();
$body = $doc->getElementsByTagName('html')->item(0)-> // <html>
@@ -99,7 +100,6 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
* To iterate is human, to recurse divine - L. Peter Deutsch
* @param DOMNode $node DOMNode to be tokenized.
* @param HTMLPurifier_Token[] $tokens Array-list of already tokenized tokens.
* @return HTMLPurifier_Token of node appended to previously passed tokens.
*/
protected function tokenizeDOM($node, &$tokens, $config)
{
@@ -281,7 +281,7 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
*/
public function callbackUndoCommentSubst($matches)
{
return '<!--' . strtr($matches[1], array('&amp;' => '&', '&lt;' => '<')) . $matches[2];
return '<!--' . $this->undoCommentSubstr($matches[1]) . $matches[2];
}
/**
@@ -292,7 +292,25 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
*/
public function callbackArmorCommentEntities($matches)
{
return '<!--' . str_replace('&', '&amp;', $matches[1]) . $matches[2];
return '<!--' . $this->armorEntities($matches[1]) . $matches[2];
}
/**
* @param string $string
* @return string
*/
protected function armorEntities($string)
{
return str_replace('&', '&amp;', $string);
}
/**
* @param string $string
* @return string
*/
protected function undoCommentSubstr($string)
{
return strtr($string, array('&amp;' => '&', '&lt;' => '<'));
}
/**
@@ -328,6 +346,66 @@ class HTMLPurifier_Lexer_DOMLex extends HTMLPurifier_Lexer
$ret .= '</body></html>';
return $ret;
}
/**
* @param string $html
* @return string
*/
protected function aggressivelyFixLt($html)
{
$char = '[^a-z!\/]';
$html = $this->manipulateHtmlComments($html, array($this, 'armorEntities'));
do {
$old = $html;
$html = preg_replace("/<($char)/i", '&lt;\\1', $html);
} while ($html !== $old);
return $this->manipulateHtmlComments($html, array($this, 'undoCommentSubstr'));
}
/**
* Modify HTML comments in the given HTML content using a callback.
*
* @param string $html
* @param callable $callback
* @return string
*/
protected function manipulateHtmlComments($html, callable $callback)
{
$offset = 0;
$startTag = '<!--';
$endTag = '-->';
while (($startPos = strpos($html, $startTag, $offset)) !== false) {
$startPos += strlen($startTag); // Move past `<!--`
$endPos = strpos($html, $endTag, $startPos);
if ($endPos === false) {
// No matching ending comment tag found
break;
}
// Extract the original comment content
$commentContent = substr($html, $startPos, $endPos - $startPos);
// Apply the callback to the comment content
$newCommentContent = $callback($commentContent);
// Reconstruct the entire comment with the new content
$newComment = $startTag . $newCommentContent . $endTag;
// Replace the old comment in the HTML content with the new one
$html = substr($html, 0, $startPos - strlen($startTag)) .
$newComment .
substr($html, $endPos + strlen($endTag));
// Move offset to the end of the new comment for the next iteration
$offset = strpos($html, $newComment, $offset) + strlen($newComment);
}
return $html;
}
}
// vim: et sw=4 sts=4

View File

@@ -111,7 +111,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
if ($synchronize_interval && // synchronization is on
$cursor > 0 && // cursor is further than zero
$loops % $synchronize_interval === 0) { // time to synchronize!
$current_line = 1 + $this->substrCount($html, $nl, 0, $cursor);
$current_line = 1 + substr_count($html, $nl, 0, $cursor);
}
}
@@ -139,7 +139,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
);
if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col);
$current_line += $this->substrCount($html, $nl, $cursor, $position_next_lt - $cursor);
$current_line += substr_count($html, $nl, $cursor, $position_next_lt - $cursor);
}
$array[] = $token;
$cursor = $position_next_lt + 1;
@@ -214,7 +214,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
);
if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col);
$current_line += $this->substrCount($html, $nl, $cursor, $strlen_segment);
$current_line += substr_count($html, $nl, $cursor, $strlen_segment);
}
$array[] = $token;
$cursor = $end ? $position_comment_end : $position_comment_end + 3;
@@ -229,7 +229,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
$token = new HTMLPurifier_Token_End($type);
if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col);
$current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
$current_line += substr_count($html, $nl, $cursor, $position_next_gt - $cursor);
}
$array[] = $token;
$inside_tag = false;
@@ -248,7 +248,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
$token = new HTMLPurifier_Token_Text('<');
if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col);
$current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
$current_line += substr_count($html, $nl, $cursor, $position_next_gt - $cursor);
}
$array[] = $token;
$inside_tag = false;
@@ -276,7 +276,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
}
if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col);
$current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
$current_line += substr_count($html, $nl, $cursor, $position_next_gt - $cursor);
}
$array[] = $token;
$inside_tag = false;
@@ -310,7 +310,7 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
}
if ($maintain_line_numbers) {
$token->rawPosition($current_line, $current_col);
$current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor);
$current_line += substr_count($html, $nl, $cursor, $position_next_gt - $cursor);
}
$array[] = $token;
$cursor = $position_next_gt + 1;
@@ -343,28 +343,6 @@ class HTMLPurifier_Lexer_DirectLex extends HTMLPurifier_Lexer
return $array;
}
/**
* PHP 5.0.x compatible substr_count that implements offset and length
* @param string $haystack
* @param string $needle
* @param int $offset
* @param int $length
* @return int
*/
protected function substrCount($haystack, $needle, $offset, $length)
{
static $oldVersion;
if ($oldVersion === null) {
$oldVersion = version_compare(PHP_VERSION, '5.1', '<');
}
if ($oldVersion) {
$haystack = substr($haystack, $offset, $length);
return substr_count($haystack, $needle);
} else {
return substr_count($haystack, $needle, $offset, $length);
}
}
/**
* Takes the inside of an HTML tag and makes an assoc array of attributes.
*

View File

@@ -1223,14 +1223,14 @@ class HTML5
'type' => self::COMMENT
);
/* Otherwise if the next seven chacacters are a case-insensitive match
/* Otherwise if the next seven characters are a case-insensitive match
for the word "DOCTYPE", then consume those characters and switch to the
DOCTYPE state. */
} elseif (strtolower($this->character($this->char + 1, 7)) === 'doctype') {
$this->char += 7;
$this->state = 'doctype';
/* Otherwise, is is a parse error. Switch to the bogus comment state.
/* Otherwise, it is a parse error. Switch to the bogus comment state.
The next character that is consumed, if any, is the first character
that will be in the comment. */
} else {
@@ -4410,7 +4410,7 @@ class HTML5TreeConstructer
foreach ($token['attr'] as $attr) {
if (!$el->hasAttribute($attr['name'])) {
$el->setAttribute($attr['name'], $attr['value']);
$el->setAttribute($attr['name'], (string)$attr['value']);
}
}

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