Skip to content

Commit c8c726e

Browse files
committed
5.0.0 - Security fix.
If you had a malformed URL when using the OSC URL sequence, it would not be properly escaped. Also, html escaping is now mandatory, so the API changed. The 'escape_for_html' property was removed.
1 parent 6e19ac4 commit c8c726e

9 files changed

+37
-203
lines changed

Readme.md

+3-14
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,6 @@ See the examples directory for a complete CSS theme for these classes.
119119

120120
## Properties
121121

122-
#### escape_for_html
123-
(default: true)
124-
125-
This does the minimum escaping of text to make it compliant with HTML.
126-
In particular, the '&','<', and '>' characters are escaped. It is
127-
** highly ** recommended that you do not set this to false. It will open
128-
the door security vulnerabilities.
129-
130122
#### use_classes
131123
(default: false)
132124

@@ -140,12 +132,9 @@ This mapping is a whitelist of URI schemes that will be allowed to render HTML a
140132

141133
## Buffering
142134

143-
In general, the ansi_to_html *should* emit HTML when invoked with a non-empty string.
144-
The only exceptions are an incomplete ESC sequence or an incomplete escaped URL.
145-
For those cases, the library will buffer the escape or the sequence for the escaped URL.
146-
147-
The library is also stateful. If a color is set in a prior invocation, then it will
148-
continue to emit that color in further invocations until the color/SGR attribute is changed.
135+
In general, the ansi_to_html *should* emit HTML output when invoked with a non-empty string.
136+
The only exceptions are an incomplete ESC sequence or an incomplete OSC URL sequence.
137+
For those cases, the library will buffer (not emit output), until it receives input that completes those sequences.
149138

150139
### Example of a Use Case
151140

VERSION

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.1

ansi_up.js

+9-17
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,9 @@ var PacketKind;
3434
})(PacketKind || (PacketKind = {}));
3535
var AnsiUp = (function () {
3636
function AnsiUp() {
37-
this.VERSION = "4.0.3";
37+
this.VERSION = "5.0.0";
3838
this.setup_palettes();
3939
this._use_classes = false;
40-
this._escape_for_html = true;
4140
this.bold = false;
4241
this.fg = this.bg = null;
4342
this._buffer = '';
@@ -50,17 +49,7 @@ var AnsiUp = (function () {
5049
set: function (arg) {
5150
this._use_classes = arg;
5251
},
53-
enumerable: true,
54-
configurable: true
55-
});
56-
Object.defineProperty(AnsiUp.prototype, "escape_for_html", {
57-
get: function () {
58-
return this._escape_for_html;
59-
},
60-
set: function (arg) {
61-
this._escape_for_html = arg;
62-
},
63-
enumerable: true,
52+
enumerable: false,
6453
configurable: true
6554
});
6655
Object.defineProperty(AnsiUp.prototype, "url_whitelist", {
@@ -70,7 +59,7 @@ var AnsiUp = (function () {
7059
set: function (arg) {
7160
this._url_whitelist = arg;
7261
},
73-
enumerable: true,
62+
enumerable: false,
7463
configurable: true
7564
});
7665
AnsiUp.prototype.setup_palettes = function () {
@@ -120,13 +109,17 @@ var AnsiUp = (function () {
120109
}
121110
};
122111
AnsiUp.prototype.escape_txt_for_html = function (txt) {
123-
return txt.replace(/[&<>]/gm, function (str) {
112+
return txt.replace(/[&<>"']/gm, function (str) {
124113
if (str === "&")
125114
return "&amp;";
126115
if (str === "<")
127116
return "&lt;";
128117
if (str === ">")
129118
return "&gt;";
119+
if (str === "\"")
120+
return "&quot;";
121+
if (str === "'")
122+
return "&#x27;";
130123
});
131124
};
132125
AnsiUp.prototype.append_buffer = function (txt) {
@@ -341,8 +334,7 @@ var AnsiUp = (function () {
341334
var txt = fragment.text;
342335
if (txt.length === 0)
343336
return txt;
344-
if (this._escape_for_html)
345-
txt = this.escape_txt_for_html(txt);
337+
txt = this.escape_txt_for_html(txt);
346338
if (!fragment.bold && fragment.fg === null && fragment.bg === null)
347339
return txt;
348340
var styles = [];

ansi_up.ts

+8-19
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ interface TextPacket {
5050

5151
class AnsiUp
5252
{
53-
VERSION = "4.0.3";
53+
VERSION = "5.0.0";
5454

5555
//
5656
// *** SEE README ON GITHUB FOR PUBLIC API ***
@@ -66,7 +66,6 @@ class AnsiUp
6666
private bold:boolean;
6767

6868
private _use_classes:boolean;
69-
private _escape_for_html;
7069

7170
private _csi_regex:RegExp;
7271

@@ -82,7 +81,6 @@ class AnsiUp
8281
// All construction occurs here
8382
this.setup_palettes();
8483
this._use_classes = false;
85-
this._escape_for_html = true;
8684

8785
this.bold = false;
8886
this.fg = this.bg = null;
@@ -102,16 +100,6 @@ class AnsiUp
102100
return this._use_classes;
103101
}
104102

105-
set escape_for_html(arg:boolean)
106-
{
107-
this._escape_for_html = arg;
108-
}
109-
110-
get escape_for_html():boolean
111-
{
112-
return this._escape_for_html;
113-
}
114-
115103
set url_whitelist(arg:{})
116104
{
117105
this._url_whitelist = arg;
@@ -183,10 +171,12 @@ class AnsiUp
183171

184172
private escape_txt_for_html(txt:string):string
185173
{
186-
return txt.replace(/[&<>]/gm, (str) => {
187-
if (str === "&") return "&amp;";
188-
if (str === "<") return "&lt;";
189-
if (str === ">") return "&gt;";
174+
return txt.replace(/[&<>"']/gm, (str) => {
175+
if (str === "&") return "&amp;";
176+
if (str === "<") return "&lt;";
177+
if (str === ">") return "&gt;";
178+
if (str === "\"") return "&quot;";
179+
if (str === "'") return "&#x27;";
190180
});
191181
}
192182

@@ -631,8 +621,7 @@ class AnsiUp
631621
if (txt.length === 0)
632622
return txt;
633623

634-
if (this._escape_for_html)
635-
txt = this.escape_txt_for_html(txt);
624+
txt = this.escape_txt_for_html(txt);
636625

637626
// If colors not set, default style is used
638627
if (!fragment.bold && fragment.fg === null && fragment.bg === null)

dist/ansi_up.d.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ export default class AnsiUp {
3030
private bg;
3131
private bold;
3232
private _use_classes;
33-
private _escape_for_html;
3433
private _csi_regex;
3534
private _osc_st;
3635
private _osc_regex;
3736
private _url_whitelist;
3837
private _buffer;
3938
constructor();
40-
use_classes: boolean;
41-
escape_for_html: boolean;
42-
url_whitelist: {};
39+
set use_classes(arg: boolean);
40+
get use_classes(): boolean;
41+
set url_whitelist(arg: {});
42+
get url_whitelist(): {};
4343
private setup_palettes;
4444
private escape_txt_for_html;
4545
private append_buffer;

dist/ansi_up.js.include

+9-17
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ var PacketKind;
1515
})(PacketKind || (PacketKind = {}));
1616
var AnsiUp = (function () {
1717
function AnsiUp() {
18-
this.VERSION = "4.0.3";
18+
this.VERSION = "5.0.0";
1919
this.setup_palettes();
2020
this._use_classes = false;
21-
this._escape_for_html = true;
2221
this.bold = false;
2322
this.fg = this.bg = null;
2423
this._buffer = '';
@@ -31,17 +30,7 @@ var AnsiUp = (function () {
3130
set: function (arg) {
3231
this._use_classes = arg;
3332
},
34-
enumerable: true,
35-
configurable: true
36-
});
37-
Object.defineProperty(AnsiUp.prototype, "escape_for_html", {
38-
get: function () {
39-
return this._escape_for_html;
40-
},
41-
set: function (arg) {
42-
this._escape_for_html = arg;
43-
},
44-
enumerable: true,
33+
enumerable: false,
4534
configurable: true
4635
});
4736
Object.defineProperty(AnsiUp.prototype, "url_whitelist", {
@@ -51,7 +40,7 @@ var AnsiUp = (function () {
5140
set: function (arg) {
5241
this._url_whitelist = arg;
5342
},
54-
enumerable: true,
43+
enumerable: false,
5544
configurable: true
5645
});
5746
AnsiUp.prototype.setup_palettes = function () {
@@ -101,13 +90,17 @@ var AnsiUp = (function () {
10190
}
10291
};
10392
AnsiUp.prototype.escape_txt_for_html = function (txt) {
104-
return txt.replace(/[&<>]/gm, function (str) {
93+
return txt.replace(/[&<>"']/gm, function (str) {
10594
if (str === "&")
10695
return "&amp;";
10796
if (str === "<")
10897
return "&lt;";
10998
if (str === ">")
11099
return "&gt;";
100+
if (str === "\"")
101+
return "&quot;";
102+
if (str === "'")
103+
return "&#x27;";
111104
});
112105
};
113106
AnsiUp.prototype.append_buffer = function (txt) {
@@ -322,8 +315,7 @@ var AnsiUp = (function () {
322315
var txt = fragment.text;
323316
if (txt.length === 0)
324317
return txt;
325-
if (this._escape_for_html)
326-
txt = this.escape_txt_for_html(txt);
318+
txt = this.escape_txt_for_html(txt);
327319
if (!fragment.bold && fragment.fg === null && fragment.bg === null)
328320
return txt;
329321
var styles = [];

0 commit comments

Comments
 (0)