Skip to content

Commit d5cc3db

Browse files
committed
updates
1 parent 3435e0e commit d5cc3db

File tree

11 files changed

+84
-44
lines changed

11 files changed

+84
-44
lines changed

.github/workflows/build-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ jobs:
1515
runs-on: ubuntu-latest
1616
timeout-minutes: 10
1717
steps:
18-
- uses: actions/checkout@v4
19-
- uses: actions/setup-node@v4
18+
- uses: actions/checkout@v6
19+
- uses: actions/setup-node@v6
2020
with:
2121
node-version: 21.x
2222
- run: npm install

dist/sceditor.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/sceditor.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example/example.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<link rel="stylesheet" href="../dist/sceditor.min.css" id="theme-style" />
1010
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
1111

12-
<script src="../dist/dist/bundle.js"></script>
12+
<script src="../dist/sceditor.min.js"></script>
1313

1414
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css" rel="stylesheet">
1515
</head>
@@ -54,13 +54,13 @@ <h1>SCEditor example</h1>
5454
</footer>
5555
</div>
5656
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>
57-
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/9000.0.1/prism.min.js" integrity="sha512-UOoJElONeUNzQbbKQbjldDf9MwOHqxNz49NNJJ1d90yp+X9edsHyJoAs6O4K19CZGaIdjI5ohK+O2y5lBTW6uQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
5857
<script>
5958
var textarea = document.getElementById('example');
6059

6160
sceditor.create(textarea, {
6261
extensionsUrl: 'http://localhost/bbcode.json',
6362
autoExpand: true,
63+
autofocus: true,
6464
//locale: 'de',
6565
maxLength: 32767,
6666
plugins: 'emojis,undo,mentions,dragdrop',

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"@lodder/time-grunt": "^4.0.0",
4646
"@rollup/plugin-node-resolve": "^16.0.3",
4747
"@w8tcha/grunt-dev-update": "^2.3.4",
48-
"autoprefixer": "^10.4.23",
48+
"autoprefixer": "^10.4.24",
4949
"cssnano": "^7.1.2",
5050
"grunt": "~1.6.1",
5151
"grunt-contrib-clean": "^2.0.1",
@@ -55,7 +55,7 @@
5555
"grunt-contrib-uglify": "^5.2.2",
5656
"grunt-eslint": "^26.0.0",
5757
"grunt-rollup": "^12.0.0",
58-
"grunt-sass": "^4.0.1",
58+
"grunt-sass": "^4.1.0",
5959
"istanbul-lib-coverage": "^3.2.2",
6060
"istanbul-lib-instrument": "^6.0.3",
6161
"istanbul-lib-report": "^3.0.1",
@@ -65,10 +65,10 @@
6565
"postcss-header": "^3.0.3",
6666
"qunit": "^2.25.0",
6767
"rangy": "^1.3.2",
68-
"sass": "^1.97.1",
68+
"sass": "^1.97.3",
6969
"sinon": "^21.0.1",
70-
"webpack": "^5.104.1",
71-
"webpack-dev-server": "^5.2.2"
70+
"webpack": "^5.105.1",
71+
"webpack-dev-server": "^5.2.3"
7272
},
7373
"dependencies": {
7474
"dompurify": "^3.3.1"

src/lib/SCEditor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ export default function SCEditor(original, userOptions) {
615615
charset: options.charset,
616616
themeMode: options.themeMode,
617617
styles: styles
618-
}));
618+
}, false, false));
619619

620620
wysiwygDocument.close();
621621

src/lib/defaultCommands.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ var defaultCmds = {
274274
html += '<div class="sceditor-color-column">';
275275

276276
column.split(',').forEach(function (color) {
277+
// Only allow named, #aaa, hsl(1.1 50% / 1), etc.
278+
if (!/^[\#a-z0-9\-\(\) \/%\.]+$/i.test(color)) {
279+
color = '';
280+
}
281+
277282
html +=
278283
`<a href="#" class="sceditor-color-option" style="background-color: ${color}" data-color="${
279284
color}"></a>`;

src/lib/escape.js

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
// Must start with a valid scheme
2-
// ^
3-
// Schemes that are considered safe
4-
// (https?|s?ftp|mailto|spotify|ssh|teamspeak|tel):|
5-
// Relative schemes (//:) are considered safe
6-
// (\\/\\/)|
7-
// Image data URI's are considered safe
8-
// data:image\\/(png|bmp|gif|p?jpe?g);
9-
var VALID_SCHEME_REGEX =
10-
/^(https?|s?ftp|mailto|spotify|ssh|teamspeak|tel):|(\/\/)|data:image\/(png|bmp|gif|p?jpe?g);/i;
1+
// Regex used by DOMPurify to filter URLs. Might as well match here as otherwise
2+
// URLs will be filtered out by DOMPurify anyway
3+
var VALID_URI_REGEX = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i;
4+
// Safe image data URIs
5+
var VALID_DATA_REGEX = /^data:image\/(png|bmp|gif|p?jpe?g);/i;
6+
var WHITESPACE_REGEX = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
117

128
/**
139
* Escapes a string so it's safe to use in regex
@@ -66,14 +62,18 @@ export function entities(str, noQuotes) {
6662
*
6763
* http
6864
* https
69-
* sftp
65+
* ftps
7066
* ftp
7167
* mailto
7268
* spotify
7369
* ssh
7470
* teamspeak
7571
* tel
76-
* //
72+
* callto
73+
* sms
74+
* cid
75+
* xmpp
76+
* matrix
7777
* data:image/(png|jpeg|jpg|pjpeg|bmp|gif);
7878
*
7979
* **IMPORTANT**: This does not escape any HTML in a url, for
@@ -84,21 +84,28 @@ export function entities(str, noQuotes) {
8484
* @since 1.4.5
8585
*/
8686
export function uriScheme(url) {
87-
const hasScheme = /^[^\/]*:/i;
88-
const location = window.location;
87+
var path,
88+
location = window.location;
8989

90-
// Has no scheme or a valid scheme
91-
if ((!url || !hasScheme.test(url)) || VALID_SCHEME_REGEX.test(url)) {
90+
// Match previous behaviour for empty or data: URIs
91+
if (!url || VALID_DATA_REGEX.test(url)) {
9292
return url;
9393
}
9494

95-
const path = location.pathname.split('/');
96-
path.pop();
95+
// Invalid scheme so make relative
96+
if (!VALID_URI_REGEX.test(url.replace(WHITESPACE_REGEX, ''))) {
97+
path = location.pathname.split('/');
98+
path.pop();
9799

98-
return location.protocol +
99-
'//' +
100-
location.host +
101-
path.join('/') +
102-
'/' +
103-
url;
100+
url = location.protocol + '//' +
101+
location.host +
102+
path.join('/') + '/' +
103+
url;
104+
105+
if (!VALID_URI_REGEX.test(url.replace(WHITESPACE_REGEX, ''))) {
106+
return '';
107+
}
108+
}
109+
110+
return url;
104111
};

src/lib/templates.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as dom from './dom.js';
22
import * as escape from './escape.js';
33

4+
import DOMPurify from 'dompurify';
45

56
/**
67
* HTML templates used by the editor and default commands
@@ -137,19 +138,35 @@ var _templates = {
137138
* @param {string} name
138139
* @param {Object} [params]
139140
* @param {boolean} [createHtml]
141+
* @param {boolean} [sanitize=true]
140142
* @returns {string|DocumentFragment}
141143
* @private
142144
*/
143-
export default function(name, params, createHtml) {
145+
export default function(name, params, createHtml, sanitize) {
144146
var template = _templates[name];
145147

146148
Object.keys(params).forEach(function(name) {
149+
150+
if (typeof sanitize === 'undefined') {
151+
sanitize = false;
152+
}
153+
154+
// Default to sanitizing
155+
if (sanitize !== false) {
156+
params[name] = escape.entities(String(params[name]));
157+
}
158+
147159
template = template.replace(
148160
new RegExp(escape.regex(`{${name}}`), 'g'),
149161
params[name]
150162
);
151163
});
152164

165+
// Default to sanitizing
166+
if (sanitize !== false) {
167+
template = DOMPurify.sanitize(template, {ADD_ATTR: ['unselectable']});
168+
}
169+
153170
if (createHtml) {
154171
template = dom.parseHTML(template);
155172
}

tests/unit/formats/bbcode.parser.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -965,7 +965,7 @@ QUnit.test('[img]', function (assert) {
965965
);
966966

967967
assert.ok(
968-
!/src="jav/i.test(
968+
/src="jav&amp;/i.test(
969969
this.parser.toHTML('[img]jav&#x0A;ascript:alert(' +
970970
'String.fromCharCode(88,83,83))[/img]')
971971
),
@@ -1001,7 +1001,7 @@ QUnit.test('[url]', function (assert) {
10011001
);
10021002

10031003
assert.ok(
1004-
!/href="jav/i.test(
1004+
/href="jav&amp;/i.test(
10051005
this.parser.toHTML('[url]jav&#x0A;ascript:alert(' +
10061006
'String.fromCharCode(88,83,83))[/url]')
10071007
),

0 commit comments

Comments
 (0)