Skip to content

Commit 24abe90

Browse files
committed
html escaping
1 parent 6bb88c5 commit 24abe90

3 files changed

Lines changed: 39 additions & 48 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "rtjscomp",
3-
"version": "0.10.2",
3+
"version": "0.11.0",
44
"description": "php-like server but with javascript",
55
"repository": {
66
"type": "git",

public/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!DOCTYPE html><?
22

3-
const code = Number(input.code || 42);
3+
const code = input.code || 42;
44
// this is not php but javascript!!!!!!!!!!!!!
55
// but for better syntax highlighting, set ide language to php.
66
// open your local website and look into its source code. this script will be gone.
@@ -9,8 +9,8 @@
99
<html>
1010
<body>
1111
<h1>Hello, World!</h1>
12-
<p>Current reason: <?= code ?></p>
13-
<p><a href="/?code=<?= code + 1 ?>">One more</a></p>
12+
<p>Current reason: <?: code ?></p>
13+
<p><a href="/?code=<?: code + 1 ?>">One more</a></p>
1414
<p>See <a href="https://github.com/L3P3/rtjscomp">the readme</a>!</p>
1515
</body>
1616
</html>

rtjscomp.js

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ const COMPRESS_METHODS = ',gzip,brotli,zstd'.split(',');
2323
const GZIP_OPTIONS = {level: 9};
2424
const HAS_BROTLI = zlib.createBrotliCompress != null;
2525
const HAS_ZSTD = zlib.createZstdCompress != null;
26+
const HTML_ESCAPE_REG = /[&<>"]/g;
27+
const HTML_ESCAPE_TEST_REG = /[&<>"]/;
2628
const HTTP_LIST_REG = /,\s*/;
2729
const IMPORT_REG = /\bimport\(/g;
2830
const IPS_PRIVATE = /^(127\.|10\.|192\.168\.|::1|fc00:|fe80:)/;
@@ -148,6 +150,13 @@ const rtjscomp = global.rtjscomp = {
148150
actions,
149151
version: VERSION,
150152
};
153+
const escape_html_char = char => (
154+
char === '&' ? '&amp;' :
155+
char === '<' ? '&lt;' :
156+
char === '>' ? '&gt;' :
157+
char === '"' ? '&quot;' :
158+
char
159+
);
151160

152161
// polyfills
153162
if (!Object.fromEntries) {
@@ -158,29 +167,6 @@ if (!Object.fromEntries) {
158167
}
159168
}
160169

161-
// legacy, will be removed soon!
162-
global.globals = rtjscomp;
163-
global.actions = rtjscomp.actions;
164-
global.data_load = name => {
165-
log('[deprecated] synchronous load file: ' + PATH_DATA + name);
166-
try {
167-
return fs.readFileSync(PATH_DATA + name, 'utf8');
168-
}
169-
catch (err) {
170-
return null;
171-
}
172-
}
173-
global.data_save = (name, data) => (
174-
log('[deprecated] synchronous save file: ' + PATH_DATA + name),
175-
fs.writeFileSync(PATH_DATA + name, data, 'utf8')
176-
)
177-
global.number_check_int = number => (
178-
Math.floor(number) === number
179-
)
180-
global.number_check_uint = number => (
181-
number >= 0 && number_check_int(number)
182-
)
183-
184170
rtjscomp.data_load = async name => {
185171
if (log_verbose) log('load file: ' + PATH_DATA + name);
186172
const data = await fsp.readFile(PATH_DATA + name, 'utf8').catch(() => null);
@@ -211,6 +197,11 @@ rtjscomp.data_save = (name, data) => (
211197
'utf8'
212198
)
213199
)
200+
rtjscomp.escape_html = str => (
201+
HTML_ESCAPE_TEST_REG.test(str)
202+
? str.replace(HTML_ESCAPE_REG, escape_html_char)
203+
: str
204+
);
214205

215206
/**
216207
hack to guess the line number of an error
@@ -1182,7 +1173,7 @@ const request_handle = async (request, response, https) => {
11821173

11831174
let code = `const log=a=>rtjscomp.log(${
11841175
JSON.stringify(path + ': ')
1185-
}+a);`;
1176+
}+a),escape_html=rtjscomp.escape_html;`;
11861177

11871178
let section_dynamic = false;
11881179
let index_start = 0;
@@ -1202,28 +1193,28 @@ const request_handle = async (request, response, https) => {
12021193
section_dynamic = false;
12031194
// section not empty?
12041195
if (index_start < index_end) {
1205-
// `<?`?
1206-
if (file_content.charCodeAt(index_start) !== 61) {
1207-
code += (
1208-
file_content
1209-
.slice(
1210-
index_start,
1211-
index_end
1212-
)
1213-
.replace(IMPORT_REG, 'custom_import(') +
1214-
';'
1215-
);
1196+
let before = '';
1197+
let after = ';';
1198+
const first_char = file_content.charCodeAt(index_start);
1199+
if (first_char === 58) { // `<?:`?
1200+
++index_start;
1201+
before = 'output.write(escape_html(""+(';
1202+
after = ')));';
12161203
}
1217-
else { // `<?=`?
1218-
code += `output.write(''+(${
1219-
file_content
1220-
.slice(
1221-
++index_start,
1222-
index_end
1223-
)
1224-
.replace(IMPORT_REG, 'custom_import(')
1225-
}));`;
1204+
else if (first_char === 61) { // `<?=`?
1205+
++index_start;
1206+
before = 'output.write(""+(';
1207+
after = '));';
12261208
}
1209+
1210+
code += before + (
1211+
file_content
1212+
.slice(
1213+
index_start,
1214+
index_end
1215+
)
1216+
.replace(IMPORT_REG, 'custom_import(')
1217+
) + after;
12271218
}
12281219
// skip `?>`
12291220
index_end += 2;

0 commit comments

Comments
 (0)