Skip to content

Commit

Permalink
c02a88c3882a49f96f422743e43382586ef12c3e Fix: Potential XSS for HTML …
Browse files Browse the repository at this point in the history
…in a state name

Sync to source repo @c02a88c3882a49f96f422743e43382586ef12c3e
  • Loading branch information
dtbuild committed Apr 10, 2024
1 parent 76957cc commit 4e174ae
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 34 deletions.
2 changes: 1 addition & 1 deletion datatables.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
],
"src-repo": "http://github.com/DataTables/StateRestore",
"last-tag": "1.4.0",
"last-sync": "04ce891c83e54ac114ad999d3ae09a6939a91a18"
"last-sync": "c02a88c3882a49f96f422743e43382586ef12c3e"
}
20 changes: 18 additions & 2 deletions js/StateRestore.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ var StateRestore = /** @class */ (function () {
removeContents: $('<div class="' + this.classes.confirmationText + '"><span>' +
this.s.dt
.i18n('stateRestore.removeConfirm', this.c.i18n.removeConfirm)
.replace(/%s/g, this.s.identifier) +
.replace(/%s/g, StateRestore.entityEncode(this.s.identifier)) +
'</span></div>'),
removeError: $('<span class="' + this.classes.modalError + '">' +
this.s.dt.i18n('stateRestore.removeError', this.c.i18n.removeError) +
Expand All @@ -57,7 +57,7 @@ var StateRestore = /** @class */ (function () {
'<label class="' + this.classes.confirmationMessage + '">' +
this.s.dt
.i18n('stateRestore.renameLabel', this.c.i18n.renameLabel)
.replace(/%s/g, this.s.identifier) +
.replace(/%s/g, StateRestore.entityEncode(this.s.identifier)) +
'</label>' +
'</div>'),
renameInput: $('<input class="' + this.classes.input + '" type="text"></input>'),
Expand Down Expand Up @@ -525,6 +525,22 @@ var StateRestore = /** @class */ (function () {
this.c.ajax.call(this.s.dt, ajaxData, successCallback);
}
};
/**
* Encode HTML entities
*
* @param d String to encode
* @returns Encoded string
* @todo When DT1 support is dropped, switch to using `DataTable.util.escapeHtml`
*/
StateRestore.entityEncode = function (d) {
return typeof d === 'string' ?
d
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;') :
d;
};
/**
* Performs a deep compare of two state objects, returning true if they match
*
Expand Down
8 changes: 4 additions & 4 deletions js/StateRestoreCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,8 @@ var StateRestoreCollection = /** @class */ (function () {
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
}
Expand Down Expand Up @@ -876,8 +876,8 @@ var StateRestoreCollection = /** @class */ (function () {
var keys = Object.keys(localStorage);
var _loop_2 = function (key) {
// eslint-disable-next-line no-useless-escape
if (key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname.replace(/\//g, '/') + '$')) ||
key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname.replace(/\//g, '/') +
if (key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname + '$')) ||
key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname +
'_' + this_2.s.dt.table().node().id + '$'))) {
var loadedState_1 = JSON.parse(localStorage.getItem(key));
if (loadedState_1.stateRestore.isPreDefined ||
Expand Down
36 changes: 26 additions & 10 deletions js/dataTables.stateRestore.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ var DataTable = $.fn.dataTable;
removeContents: $$2('<div class="' + this.classes.confirmationText + '"><span>' +
this.s.dt
.i18n('stateRestore.removeConfirm', this.c.i18n.removeConfirm)
.replace(/%s/g, this.s.identifier) +
.replace(/%s/g, StateRestore.entityEncode(this.s.identifier)) +
'</span></div>'),
removeError: $$2('<span class="' + this.classes.modalError + '">' +
this.s.dt.i18n('stateRestore.removeError', this.c.i18n.removeError) +
Expand All @@ -110,7 +110,7 @@ var DataTable = $.fn.dataTable;
'<label class="' + this.classes.confirmationMessage + '">' +
this.s.dt
.i18n('stateRestore.renameLabel', this.c.i18n.renameLabel)
.replace(/%s/g, this.s.identifier) +
.replace(/%s/g, StateRestore.entityEncode(this.s.identifier)) +
'</label>' +
'</div>'),
renameInput: $$2('<input class="' + this.classes.input + '" type="text"></input>'),
Expand Down Expand Up @@ -578,6 +578,22 @@ var DataTable = $.fn.dataTable;
this.c.ajax.call(this.s.dt, ajaxData, successCallback);
}
};
/**
* Encode HTML entities
*
* @param d String to encode
* @returns Encoded string
* @todo When DT1 support is dropped, switch to using `DataTable.util.escapeHtml`
*/
StateRestore.entityEncode = function (d) {
return typeof d === 'string' ?
d
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;') :
d;
};
/**
* Performs a deep compare of two state objects, returning true if they match
*
Expand Down Expand Up @@ -1360,8 +1376,8 @@ var DataTable = $.fn.dataTable;
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
}
Expand Down Expand Up @@ -1711,8 +1727,8 @@ var DataTable = $.fn.dataTable;
var keys = Object.keys(localStorage);
var _loop_2 = function (key) {
// eslint-disable-next-line no-useless-escape
if (key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname.replace(/\//g, '/') + '$')) ||
key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname.replace(/\//g, '/') +
if (key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname + '$')) ||
key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname +
'_' + this_2.s.dt.table().node().id + '$'))) {
var loadedState_1 = JSON.parse(localStorage.getItem(key));
if (loadedState_1.stateRestore.isPreDefined ||
Expand Down Expand Up @@ -2159,8 +2175,8 @@ var DataTable = $.fn.dataTable;
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
dt.button('SaveStateRestore:name').collectionRebuild(stateButtons);
Expand Down Expand Up @@ -2306,8 +2322,8 @@ var DataTable = $.fn.dataTable;
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion js/dataTables.stateRestore.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions js/dataTables.stateRestore.min.mjs

Large diffs are not rendered by default.

36 changes: 26 additions & 10 deletions js/dataTables.stateRestore.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ let $ = jQuery;
removeContents: $$2('<div class="' + this.classes.confirmationText + '"><span>' +
this.s.dt
.i18n('stateRestore.removeConfirm', this.c.i18n.removeConfirm)
.replace(/%s/g, this.s.identifier) +
.replace(/%s/g, StateRestore.entityEncode(this.s.identifier)) +
'</span></div>'),
removeError: $$2('<span class="' + this.classes.modalError + '">' +
this.s.dt.i18n('stateRestore.removeError', this.c.i18n.removeError) +
Expand All @@ -70,7 +70,7 @@ let $ = jQuery;
'<label class="' + this.classes.confirmationMessage + '">' +
this.s.dt
.i18n('stateRestore.renameLabel', this.c.i18n.renameLabel)
.replace(/%s/g, this.s.identifier) +
.replace(/%s/g, StateRestore.entityEncode(this.s.identifier)) +
'</label>' +
'</div>'),
renameInput: $$2('<input class="' + this.classes.input + '" type="text"></input>'),
Expand Down Expand Up @@ -538,6 +538,22 @@ let $ = jQuery;
this.c.ajax.call(this.s.dt, ajaxData, successCallback);
}
};
/**
* Encode HTML entities
*
* @param d String to encode
* @returns Encoded string
* @todo When DT1 support is dropped, switch to using `DataTable.util.escapeHtml`
*/
StateRestore.entityEncode = function (d) {
return typeof d === 'string' ?
d
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;') :
d;
};
/**
* Performs a deep compare of two state objects, returning true if they match
*
Expand Down Expand Up @@ -1320,8 +1336,8 @@ let $ = jQuery;
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
}
Expand Down Expand Up @@ -1671,8 +1687,8 @@ let $ = jQuery;
var keys = Object.keys(localStorage);
var _loop_2 = function (key) {
// eslint-disable-next-line no-useless-escape
if (key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname.replace(/\//g, '/') + '$')) ||
key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname.replace(/\//g, '/') +
if (key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname + '$')) ||
key.match(new RegExp('^DataTables_stateRestore_.*_' + location.pathname +
'_' + this_2.s.dt.table().node().id + '$'))) {
var loadedState_1 = JSON.parse(localStorage.getItem(key));
if (loadedState_1.stateRestore.isPreDefined ||
Expand Down Expand Up @@ -2119,8 +2135,8 @@ let $ = jQuery;
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
dt.button('SaveStateRestore:name').collectionRebuild(stateButtons);
Expand Down Expand Up @@ -2266,8 +2282,8 @@ let $ = jQuery;
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
}
Expand Down
8 changes: 4 additions & 4 deletions js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,8 @@ DataTable.ext.buttons.createState = {
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
dt.button('SaveStateRestore:name').collectionRebuild(stateButtons);
Expand Down Expand Up @@ -462,8 +462,8 @@ function _stateRegen(dt, src) {
split: split
},
extend: 'stateRestore',
text: state.s.identifier,
popoverTitle: state.s.identifier
text: StateRestore.entityEncode(state.s.identifier),
popoverTitle: StateRestore.entityEncode(state.s.identifier)
});
}
}
Expand Down

0 comments on commit 4e174ae

Please sign in to comment.