379 lines
7.7 KiB
JavaScript

'use strict';
// TODO: remove factory stuff, not needed
function factory (type, config, load, typed, math) {
/**
* Get a property of a plain object
* Throws an error in case the object is not a plain object or the
* property is not defined on the object itself
* @param {Object} object
* @param {string} prop
* @return {*} Returns the property value when safe
*/
function getSafeProperty (object, prop) {
// only allow getting properties of a plain object
if (isPlainObject(object)) {
// only allow getting properties defined on the object itself,
// not inherited from it's prototype.
if (Object.hasOwnProperty.call(object, prop)) {
return object[prop];
}
if (!(prop in object)) {
// this is a not existing property on a plain object
return undefined;
}
}
if (typeof object[prop] === 'function' && isSafeMethod(object, prop)) {
throw new Error('Cannot access method "' + prop + '" as a property');
}
throw new Error('No access to property "' + prop + '"');
}
/**
* Set a property on a plain object.
* Throws an error in case the object is not a plain object or the
* property would override an inherited property like .constructor or .toString
* @param {Object} object
* @param {string} prop
* @param {*} value
* @return {*} Returns the value
*/
// TODO: merge this function into access.js?
function setSafeProperty (object, prop, value) {
// only allow setting properties of a plain object
if (isPlainObject(object)) {
// only allow setting properties defined on the object itself,
// not inherited from it's prototype.
if (prop in object) {
// property already exists
// override when the property is defined on the object itself.
// don't allow overriding inherited properties like .constructor or .toString
if (Object.hasOwnProperty.call(object, prop)) {
return object[prop] = value;
}
}
else {
// this is a new property, that's just ok
return object[prop] = value;
}
}
throw new Error('No access to property "' + prop + '"');
}
/**
* Validate whether a method is safe.
* Throws an error when that's not the case.
* @param {Object} object
* @param {string} method
*/
// TODO: merge this function into assign.js?
function validateSafeMethod (object, method) {
if (!isSafeMethod(object, method)) {
throw new Error('No access to method "' + method + '"');
}
}
function isSafeMethod (object, method) {
// TODO: remove this, replace with whitelist
if (method === 'constructor') {
return false;
}
// test for plain functions defined on the object (instead of a method)
if (Object.hasOwnProperty.call(object, method) && isPlainObject(object)) {
return true;
}
// only allow methods from the whitelist
// TODO: also check whether this method is supported on given object
return safeMethods[method];
}
function isPlainObject (object) {
// TODO: improve this function
return typeof object === 'object' && object && object.constructor === Object;
}
return {
getSafeProperty: getSafeProperty,
setSafeProperty: setSafeProperty,
validateSafeMethod: validateSafeMethod
}
}
// whitelist of safe methods
var safeMethods = {
abs: true,
absoluteValue: true,
acos: true,
acosh: true,
acot: true,
acoth: true,
acsc: true,
acsch: true,
add: true,
and: true,
arg: true,
asec: true,
asech: true,
asin: true,
asinh: true,
atan: true,
atan2: true,
atanh: true,
bellNumbers: true,
bignumber: true,
bitAnd: true,
bitNot: true,
bitOr: true,
bitXor: true,
boolean: true,
catalan: true,
cbrt: true,
ceil: true,
chain: true,
clone: true,
cloneDeep: true,
cmp: true,
combinations: true,
compare: true,
comparedTo: true,
compile: true,
complex: true,
composition: true,
concat: true,
config: true,
conj: true,
conjugate: true,
cos: true,
cosh: true,
cosine: true,
cot: true,
coth: true,
create: true,
createUnit: true,
cross: true,
csc: true,
csch: true,
cube: true,
cubeRoot: true,
decimalPlaces: true,
deepEqual: true,
derivative: true,
det: true,
diag: true,
diagonal: true,
distance: true,
div: true,
divToInt: true,
divide: true,
dividedBy: true,
dividedToIntegerBy: true,
done: true,
dot: true,
dotDivide: true,
dotMultiply: true,
dotPow: true,
dp: true,
emit: true,
eq: true,
equal: true,
equalBase: true,
equals: true,
erf: true,
eval: true,
exp: true,
eye: true,
factorial: true,
filter: true,
fix: true,
flatten: true,
floor: true,
forEach: true,
format: true,
formatUnits: true,
fraction: true,
gamma: true,
gcd: true,
greaterThan: true,
greaterThanOrEqualTo: true,
gt: true,
gte: true,
hasBase: true,
help: true,
hyperbolicCosine: true,
hyperbolicSine: true,
hyperbolicTangent: true,
hypot: true,
im: true,
import: true,
index: true,
intersect: true,
inv: true,
inverse: true,
inverseCosine: true,
inverseHyperbolicCosine: true,
inverseHyperbolicSine: true,
inverseHyperbolicTangent: true,
inverseSine: true,
inverseTangent: true,
isFinite: true,
isInt: true,
isInteger: true,
isNaN: true,
isNeg: true,
isNegative: true,
isNumeric: true,
isPos: true,
isPositive: true,
isPrime: true,
isZero: true,
kldivergence: true,
kron: true,
larger: true,
largerEq: true,
lcm: true,
leftShift: true,
lessThan: true,
lessThanOrEqualTo: true,
ln: true,
log: true,
log10: true,
log2: true,
logarithm: true,
lsolve: true,
lt: true,
lte: true,
lup: true,
lusolve: true,
mad: true,
map: true,
matrix: true,
max: true,
mean: true,
median: true,
min: true,
minus: true,
mod: true,
mode: true,
modulo: true,
mul: true,
multinomial: true,
multiply: true,
naturalExponential: true,
naturalLogarithm: true,
neg: true,
negated: true,
noConflict: true,
norm: true,
not: true,
nthRoot: true,
number: true,
off: true,
on: true,
once: true,
ones: true,
or: true,
parse: true,
parser: true,
partitionSelect: true,
permutations: true,
pickRandom: true,
plus: true,
pow: true,
precision: true,
print: true,
prod: true,
quantileSeq: true,
random: true,
randomInt: true,
range: true,
re: true,
reshape: true,
resize: true,
rightArithShift: true,
rightLogShift: true,
round: true,
sd: true,
sec: true,
sech: true,
set: true,
sign: true,
simplify: true,
sin: true,
sine: true,
sinh: true,
size: true,
slu: true,
smaller: true,
smallerEq: true,
sort: true,
sparse: true,
splitUnit: true,
sqrt: true,
square: true,
squareRoot: true,
squeeze: true,
std: true,
stirlingS2: true,
string: true,
sub: true,
subset: true,
subtract: true,
sum: true,
swapRows: true,
tan: true,
tangent: true,
tanh: true,
times: true,
to: true,
toArray: true,
toBinary: true,
toContinued: true,
toDP: true,
toDecimalPlaces: true,
toExponential: true,
toFixed: true,
toFraction: true,
toHex: true,
toHexadecimal: true,
toJSON: true,
toLatex: true,
toNearest: true,
toNumber: true,
toNumeric: true,
toOctal: true,
toPower: true,
toPrecision: true,
toSD: true,
toSignificantDigits: true,
toString: true,
toTex: true,
toVector: true,
trace: true,
transform: true,
transpose: true,
traverse: true,
trunc: true,
truncated: true,
typed: true,
typeof: true,
unaryMinus: true,
unaryPlus: true,
unequal: true,
unit: true,
usolve: true,
valueOf: true,
var: true,
xgcd: true,
xor: true,
zeros: true
}
exports.factory = factory;
exports.math = true;