Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix element id is not escaped properly in IE #4666

Merged
merged 76 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
3baec6f
escape colon since IE doesn't support CSS escape
limingli0707 Apr 30, 2021
c93c398
test
limingli0707 Apr 30, 2021
3a0b744
fix typo
limingli0707 May 3, 2021
e7d7107
fix typo
limingli0707 May 3, 2021
a450779
refactor to a general solution for IE
limingli0707 May 15, 2021
2f7d69f
rename unit test and update change md
limingli0707 May 17, 2021
271186e
add test for dot
limingli0707 May 17, 2021
742e4d2
update unit test
limingli0707 May 17, 2021
277edee
manual test
limingli0707 May 17, 2021
0005a30
formatting
limingli0707 May 17, 2021
4c51eb5
unit test
limingli0707 May 17, 2021
edfebce
address code review comments
limingli0707 May 19, 2021
d89963f
formatting
limingli0707 May 19, 2021
e96c21d
formatting
limingli0707 May 19, 2021
e4eae62
update version
limingli0707 May 20, 2021
165eb97
escape colon since IE doesn't support CSS escape
limingli0707 Apr 30, 2021
0b7ffeb
test
limingli0707 Apr 30, 2021
81aa52d
fix typo
limingli0707 May 3, 2021
0b3e635
fix typo
limingli0707 May 3, 2021
bb2cfe5
refactor to a general solution for IE
limingli0707 May 15, 2021
fff9cda
rename unit test and update change md
limingli0707 May 17, 2021
25329e7
add test for dot
limingli0707 May 17, 2021
8613e48
update unit test
limingli0707 May 17, 2021
6ac7461
manual test
limingli0707 May 17, 2021
58ce665
formatting
limingli0707 May 17, 2021
ccae068
unit test
limingli0707 May 17, 2021
3bc82bd
address code review comments
limingli0707 May 19, 2021
f54d926
formatting
limingli0707 May 19, 2021
7e2fde5
formatting
limingli0707 May 19, 2021
7f9efa3
update version
limingli0707 May 20, 2021
448fab7
Fix: doubled changelog entry
sculpt0r May 24, 2021
168eaae
Merge branch 't/4664' of github.com:limingli0707/ckeditor4 into t/4664
limingli0707 May 24, 2021
b12d530
fix change log
limingli0707 May 24, 2021
c77b480
refactor
limingli0707 May 24, 2021
78bd393
escape colon since IE doesn't support CSS escape
limingli0707 Apr 30, 2021
45855a0
test
limingli0707 Apr 30, 2021
fe33c97
fix typo
limingli0707 May 3, 2021
68d81a1
fix typo
limingli0707 May 3, 2021
266d91d
refactor to a general solution for IE
limingli0707 May 15, 2021
f84adf0
rename unit test and update change md
limingli0707 May 17, 2021
b3138d2
add test for dot
limingli0707 May 17, 2021
c297f72
update unit test
limingli0707 May 17, 2021
9227f9b
manual test
limingli0707 May 17, 2021
8841bed
formatting
limingli0707 May 17, 2021
95e573d
unit test
limingli0707 May 17, 2021
21784b6
address code review comments
limingli0707 May 19, 2021
6126f7a
formatting
limingli0707 May 19, 2021
0399a13
formatting
limingli0707 May 19, 2021
e3e838b
update version
limingli0707 May 20, 2021
cc9c761
escape colon since IE doesn't support CSS escape
limingli0707 Apr 30, 2021
47da336
test
limingli0707 Apr 30, 2021
212c4a3
fix typo
limingli0707 May 3, 2021
9ecfe64
fix typo
limingli0707 May 3, 2021
96338a4
refactor to a general solution for IE
limingli0707 May 15, 2021
d3b2c30
rename unit test and update change md
limingli0707 May 17, 2021
8ca2aed
add test for dot
limingli0707 May 17, 2021
96cf35e
update unit test
limingli0707 May 17, 2021
3f744f6
manual test
limingli0707 May 17, 2021
53c2bea
formatting
limingli0707 May 17, 2021
032c55d
unit test
limingli0707 May 17, 2021
912e0b7
address code review comments
limingli0707 May 19, 2021
980bdb6
formatting
limingli0707 May 19, 2021
8b4299c
formatting
limingli0707 May 19, 2021
ef44d74
update version
limingli0707 May 20, 2021
e639a46
Fix: doubled changelog entry
sculpt0r May 24, 2021
bc597fe
refactor
limingli0707 May 24, 2021
0b330fe
Merge branch 't/4664' of github.com:limingli0707/ckeditor4 into t/4664
limingli0707 May 26, 2021
374d5d8
refactor
limingli0707 May 26, 2021
9972169
add manual test
limingli0707 May 26, 2021
302a247
manual test
limingli0707 May 26, 2021
f447cb4
Join `if` line with first condition - readability
sculpt0r May 27, 2021
7ee7ebd
Correct indent styles, add tableselection plugin
sculpt0r May 27, 2021
c257a73
Make escapecssuploadimage test actually works
sculpt0r May 27, 2021
a8399c3
Update LICENCE with css.escape polyfill credits
sculpt0r May 27, 2021
869ddbf
Add changelog, add lost entry for 4.16.1
sculpt0r May 27, 2021
39a8441
Style corrections in LICENSE [skip ci]
sculpt0r May 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ CKEditor 4 Changelog
## CKEditor 4.16.2

Fixed Issues:
* [#4666](/~https://github.com/ckeditor/ckeditor4/pull/4666): [IE] Introduce CSS.escape polyfill. Thanks to [limingli0707](/~https://github.com/limingli0707)!
* [#681](/~https://github.com/ckeditor/ckeditor4/issues/681): Fixed: Table elements (td, tr, th, ..) with an id that starts with dot (.) causes javascript runtime err.
* [#641](/~https://github.com/ckeditor/ckeditor4/issues/641): Fixed: UploadImage Plugin Widgets not working in IE, Opera, Safari, PhantomJS.
* [#3638](/~https://github.com/ckeditor/ckeditor4/issues/3638): Fixed: Opening the same dialog twice causes it to become hidden under the dialog's page cover.
* [#4247](/~https://github.com/ckeditor/ckeditor4/issues/4247): Fixed: [Color Button](https://ckeditor.com/cke4/addon/colorbutton)'s incorrect rendering on the first opening.

Expand All @@ -17,7 +20,7 @@ Fixed Issues:
* [#4351](/~https://github.com/ckeditor/ckeditor4/issues/4351): Fixed: Incorrect values for RGBA/HSLA colors in [Color Dialog](https://ckeditor.com/cke4/addon/colordialog).
* [#4509](/~https://github.com/ckeditor/ckeditor4/issues/4509): Fixed: Incorrect handling of drag & drop inside [widgets](https://ckeditor.com/cke4/addon/widget) and nested editables.
* [#4611](/~https://github.com/ckeditor/ckeditor4/issues/4611): [Android, iOS] Fixed: Incorrect hover styles for buttons in the toolbar on mobile devices.
* [#4652](/~https://github.com/ckeditor/ckeditor4/issues/4652): Fixed: [Event data](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_eventInfo.html) set to `false` is treated as an event cancellation.
* [#4652](/~https://github.com/ckeditor/ckeditor4/issues/4652): Fixed: [Event data](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_eventInfo.html) set to `false` is treated as an event cancelation.
* [#4659](/~https://github.com/ckeditor/ckeditor4/issues/4659): Fixed: [`CKEDITOR.htmlParser`](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_htmlParser.html) does not treat `--!>` as a comment end tag correctly.

## CKEditor 4.16
Expand Down
1 change: 1 addition & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The following libraries are included in CKEditor under the MIT license (see Appe
* PicoModal (included in `samples/js/sf.js`) - Copyright (c) 2012 James Frasca.
* CodeMirror (included in the samples) - Copyright (C) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others.
* ES6Promise - Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors.
* A polyfill for `CSS.escape` (adopted with modifications in `core/tools.js`), Mathias Bynens, v1.5.1, https://mths.be/cssescape.

Parts of code taken from the following libraries are included in CKEditor under the MIT license (see Appendix D):

Expand Down
80 changes: 74 additions & 6 deletions core/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,78 @@
} else {
return namedEntities[ code ];
}
},
// This is the polyill for the CSS.escape for IE. (#681)
// /~https://github.com/mathiasbynens/CSS.escape/blob/master/css.escape.js
cssEscapeForIE = function( selector ) {
var stringifiedSelector = String( selector ),
selectorLength = stringifiedSelector.length,
index = -1,
codeUnit,
result = '',
firstCodeUnit = stringifiedSelector.charCodeAt( 0 ),
UTF16 = {
NULL: 0x0000,
START_OF_HEADING: 0x0001,
UNIT_SEPARATOR: 0x001F,
DELETE: 0x007F,
DIGIT_ZERO: 0x0030,
DIGIT_NINE: 0x0039,
HYPHEN_MINUS: 0x002D,
LOW_LINE: 0x005F,
START_OF_LATIN_1_SUPPLEMENT: 0x0080,
CAPITAL_LETTER_A: 0x0041,
CAPITAL_LETTER_Z: 0x005A,
SMALL_LETTER_A: 0x0061,
SMALL_LETTER_Z: 0x007A
};

// Helper function to check if value is in the range.
function isInRange( value, min, max ) {
return value >= min && value <= max;
}

while ( ++index < selectorLength ) {
codeUnit = stringifiedSelector.charCodeAt( index );

if ( codeUnit == UTF16.NULL ) {
result += '\uFFFD';
continue;
}

if ( codeUnit == UTF16.DELETE ||
sculpt0r marked this conversation as resolved.
Show resolved Hide resolved
isInRange( codeUnit, UTF16.START_OF_HEADING, UTF16.UNIT_SEPARATOR ) ||
( index == 0 && isInRange( codeUnit, UTF16.DIGIT_ZERO, UTF16.DIGIT_NINE ) ) ||
( index == 1 && isInRange( codeUnit, UTF16.DIGIT_ZERO, UTF16.DIGIT_NINE ) && firstCodeUnit == UTF16.HYPHEN_MINUS )
) {
// https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
result += '\\' + codeUnit.toString( 16 ) + ' ';
continue;
}

if ( index == 0 && selectorLength == 1 && codeUnit == UTF16.HYPHEN_MINUS ) {
result += '\\' + stringifiedSelector.charAt( index );
continue;
}

if (
codeUnit >= UTF16.START_OF_LATIN_1_SUPPLEMENT ||
codeUnit == UTF16.HYPHEN_MINUS ||
codeUnit == UTF16.LOW_LINE ||
isInRange( codeUnit, UTF16.DIGIT_ZERO, UTF16.DIGIT_NINE ) ||
isInRange( codeUnit, UTF16.CAPITAL_LETTER_A, UTF16.CAPITAL_LETTER_Z ) ||
isInRange( codeUnit, UTF16.SMALL_LETTER_A, UTF16.SMALL_LETTER_Z )
) {
// the character itself
result += stringifiedSelector.charAt( index );
continue;
}

// Otherwise, the escaped character.
// https://drafts.csswg.org/cssom/#escape-a-character
result += '\\' + stringifiedSelector.charAt( index );
}
return result;
};

CKEDITOR.on( 'reset', function() {
Expand Down Expand Up @@ -1547,12 +1619,8 @@
return CSS.escape( selector );
}

// Simple leading digit escape.
if ( !isNaN( parseInt( selector.charAt( 0 ), 10 ) ) ) {
return '\\3' + selector.charAt( 0 ) + ' ' + selector.substring( 1, selector.length );
}

return selector;
// (#681)
return cssEscapeForIE( selector );
},

/**
Expand Down
43 changes: 43 additions & 0 deletions tests/core/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,49 @@
assert.areSame( escapedSelector, '\\30 ', 'only-one-number selector' );
},

// (#681)
'test escapeCss - escaped colon in the css selector': function() {
sculpt0r marked this conversation as resolved.
Show resolved Hide resolved
var selector = 'abc:def',
escapedSelector = CKEDITOR.tools.escapeCss( selector );

assert.areSame( escapedSelector, 'abc\\:def', 'The colon character is not escaped in CSS selector.' );
},

// (#681)
'test escapeCss - escaped dot in the css selector': function() {
var selector = 'abc.def',
escapedSelector = CKEDITOR.tools.escapeCss( selector );

assert.areSame( escapedSelector, 'abc\\.def', 'The dot character is not escaped in CSS selector.' );
},

// (#681)
'test escapeCss - escaped null in the css selector': function() {
var selector = 'a\0',
escapedSelector = CKEDITOR.tools.escapeCss( selector );

assert.areSame( escapedSelector, 'a\uFFFD', 'The null character is not escaped in CSS selector.' );
},

// (#681)
'test escapeCss - escaped U+0001 to U+001F or U+007F in the css selector': function() {
var selector = '\x7F\x01\x02\x1E\x1F',
escapedSelector = CKEDITOR.tools.escapeCss( selector );

assert.areSame( escapedSelector, '\\7f \\1 \\2 \\1e \\1f ', 'Character from U+0001 to U+001F or U+007F is not escaped in CSS selector.' );
},

// (#681)
'test escapeCss - escaped U+002D in the css selector': function() {
var selectorWithSecondCharIsNumber = '-1a',
escapedSelectorWithSecondCharIsNumber = CKEDITOR.tools.escapeCss( selectorWithSecondCharIsNumber ),
selectorWithSecondCharIsNotNumber = '-a',
escapedSelectorWithSecondCharNotNumber = CKEDITOR.tools.escapeCss( selectorWithSecondCharIsNotNumber );

assert.areSame( escapedSelectorWithSecondCharIsNumber, '-\\31 a', 'has U+002D in selector and second character and is in the range [0-9]' );
assert.areSame( escapedSelectorWithSecondCharNotNumber, '-a', 'has U+002D in selector and second character and is not in the range [0-9]' );
},

'test escapeCss - standard selector': function() {
var selector = 'aaa';
var escapedSelector = CKEDITOR.tools.escapeCss( selector );
Expand Down
58 changes: 58 additions & 0 deletions tests/core/tools/manual/escapecss.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<textarea id="editor1">
<table border="0" cellpadding="0" cellspacing="0" class="finTable" style="width: 100%; text-indent: 0px; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">
<tr style="vertical-align: bottom; background-color: rgb(204, 238, 255);">
<td style="font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
<td id=".lead.D2" style="padding-bottom: 1px; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
<td colspan="2" id=".amt.D2" style="text-align: center; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt; margin-left: 0pt; border-bottom-color: rgb(0, 0, 0); border-bottom-width: 1px; border-bottom-style: solid;">
<p style="margin: 0pt; text-align: center; font-family: Times New Roman, Times, serif; font-size: 10pt;">
<b><b><b>April 2, 2017</b></b></b>
</p>
</td>
<td id=".trail.D2" style="padding-bottom: 1px; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
<td id=".lead.D3" style="padding-bottom: 1px; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
<td colspan="2" id=".amt.D3" style="text-align: center; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt; margin-left: 0pt; border-bottom-color: rgb(0, 0, 0); border-bottom-width: 1px; border-bottom-style: solid;">
<p style="margin: 0pt; text-align: center; font-family: Times New Roman, Times, serif; font-size: 10pt;">
<b><b><b>July 3, 2016</b></b></b>
</p>
</td>
<td id=".trail.D3" style="padding-bottom: 1px; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
</tr>
<tr style="vertical-align: bottom; background-color: rgb(255, 255, 255);">
<td>&nbsp;</td>
<td id=".lead.B2">&nbsp;</td>
<td id=".symb.B2">&nbsp;</td>
<td id=".amt.B2" style="text-align: center;"><i>(unaudited)</i></td>
<td id=".trail.B2">&nbsp;</td>
<td id=".lead.B3">&nbsp;</td>
<td id=".symb.B3">&nbsp;</td>
<td id=".amt.B3">&nbsp;</td>
<td id=".trail.B3">&nbsp;</td>
</tr>

<tr style="vertical-align: bottom; background-color: rgb(255, 255, 255);">
<td style="font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">
<p style="font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt; margin-top: 0pt; margin-bottom: 0pt;">Property, plant and equipment, net</p>
</td>
<td id=".lead.2" style="width: 1%; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
<td id=".symb.2" style="width: 1%; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
<td id=".amt.2" style="width: 12%; text-align: right; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt; margin-left: 0pt;"><em data-td-fact-id="17716072" style="font-style: normal; font-weight: inherit;">154,668</em></td>
<td id=".trail.2" nowrap="true" style="width: 1%; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt; margin-left: 0pt;">&nbsp;</td>
<td id=".lead.3" style="width: 1%; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
<td id=".symb.3" style="width: 1%; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt;">&nbsp;</td>
<td id=".amt.3" style="width: 12%; text-align: right; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt; margin-left: 0pt;"><em data-td-fact-id="17716073" style="font-style: normal; font-weight: inherit;">171,362</em></td>
<td id=".trail.3" nowrap="true" style="width: 1%; font-family: &quot;Times New Roman&quot;, Times, serif; font-size: 10pt; margin-left: 0pt;">&nbsp;</td>
</tr>
</table>
</textarea>

<script>
( function() {
if ( !CKEDITOR.env.ie ) {
return bender.ignore();
}

CKEDITOR.replace( 'editor1', {
allowedContent: true
} );
} )();
</script>
10 changes: 10 additions & 0 deletions tests/core/tools/manual/escapecss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@bender-tags: 4.16.2, bug, 681
sculpt0r marked this conversation as resolved.
Show resolved Hide resolved
@bender-ui: collapsed
@bender-ckeditor-plugins: wysiwygarea, tableselection, elementspath

1. Open developer console.
2. Select the table cell with "April 2, 2017".

**Expected** There are no errors in the console.

**Unexpected** There is Syntax Error in the console pointing to querySelector function.
11 changes: 11 additions & 0 deletions tests/plugins/uploadwidget/manual/escapecssuploadimage.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div id="edito,r" name="edito,r" contenteditable="true">
<p>Hello World</p>
</div>

<script>
( function() {
CKEDITOR.inline( 'edito,r', {
uploadUrl: '%BASE_PATH%'
} );
} )();
</script>
13 changes: 13 additions & 0 deletions tests/plugins/uploadwidget/manual/escapecssuploadimage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@bender-tags: 4.16.2, bug, 641
@bender-ui: collapsed
@bender-ckeditor-plugins: image, uploadimage, floatingspace
@bender-include: _helpers/xhr.js

**Note:** This test use upload mock which will show you *Lena* instead of the real uploaded image.

1. Open developer console.
2. Drag and drop some image into editor.

**Expected** Image is uploaded and inserted into editor.

**Unexpected** Image is uploaded but not inserted into editor.