(core) Fix issue with lodash's map interpreting objects with length as array-like

Summary:
Here's a series of badness that easily leads to a crash, in reverse order:
- Lodash's map() function interprets an object with a .length property as an array.
- Some very old code generated human-friendly descriptions of user actions,
  applying map() to parts of them. It so happens that this generated description
  isn't even used.
- If a user action is encountered with a sufficiently large length propery,
  map() would exhaust the server memory.

Fixed by removing old unneeded code, and replacing some other occurrences of
lodash's map() with native equivalents.

Test Plan: Tested manually on a local reproduction of the issue.

Reviewers: paulfitz

Reviewed By: paulfitz

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D3938
This commit is contained in:
Dmitry S
2023-07-01 14:31:21 -04:00
parent b0aa17c932
commit 2b581ab7dc
6 changed files with 16 additions and 119 deletions

View File

@@ -3,7 +3,6 @@
const _ = require('underscore');
const ko = require('knockout');
const moment = require('moment-timezone');
const {getSelectionDesc} = require('app/common/DocActions');
const {nativeCompare, roundDownToMultiple, waitObs} = require('app/common/gutil');
const gutil = require('app/common/gutil');
const MANUALSORT = require('app/common/gristTypes').MANUALSORT;
@@ -646,20 +645,7 @@ BaseView.prototype.sendPasteActions = function(cutCallback, actions) {
// If the cut occurs on an edit restricted cell, there may be no cut action.
if (cutAction) { actions.unshift(cutAction); }
}
return this.gristDoc.docData.sendActions(actions,
this._getPasteDesc(actions[actions.length - 1], cutAction));
};
/**
* Returns a string which describes a cut/copy action.
*/
BaseView.prototype._getPasteDesc = function(pasteAction, optCutAction) {
if (optCutAction) {
return `Moved ${getSelectionDesc(optCutAction, true)} to ` +
`${getSelectionDesc(pasteAction, true)}.`;
} else {
return `Pasted data to ${getSelectionDesc(pasteAction, true)}.`;
}
return this.gristDoc.docData.sendActions(actions);
};
BaseView.prototype.buildDom = function() {