Files
meteor/packages/minimongo/helpers.js
David Glasser 9187c554c0 Ban inserting EJSON custom types as documents
Follow-up to 63b3119; further addresses #2095.

There were a few problems here:

- We didn't check that the argument to insert was a document.  (EJSON
  custom types don't count as documents, because they don't have _ids!)

- The check to see if something coming from the database was an EJSON
  custom type didn't match the check in ejson.js (specifically, it was
  missing size===2). This made it sort of look like you could use EJSON
  custom types as top-level documents, until a change in the MongoDB
  driver made made that coincidental almost-working code stop working.

- The replaceNames function wasn't documented as only taking pure JSON,
  so it wasn't obvious that "it throws when there's a Buffer" was a bug
  in the caller rather than a bug in replaceNames.

This should all be resolved now.  Use cases like CollectionFS which were
mislead by these bugs into believing that an EJSON custom type could be
a document should move their custom type into a field.
2014-05-01 13:57:35 -07:00

46 lines
1.4 KiB
JavaScript

// Like _.isArray, but doesn't regard polyfilled Uint8Arrays on old browsers as
// arrays.
// XXX maybe this should be EJSON.isArray
isArray = function (x) {
return _.isArray(x) && !EJSON.isBinary(x);
};
// XXX maybe this should be EJSON.isObject, though EJSON doesn't know about
// RegExp
// XXX note that _type(undefined) === 3!!!!
isPlainObject = LocalCollection._isPlainObject = function (x) {
return x && LocalCollection._f._type(x) === 3;
};
isIndexable = function (x) {
return isArray(x) || isPlainObject(x);
};
// Returns true if this is an object with at least one key and all keys begin
// with $. Unless inconsistentOK is set, throws if some keys begin with $ and
// others don't.
isOperatorObject = function (valueSelector, inconsistentOK) {
if (!isPlainObject(valueSelector))
return false;
var theseAreOperators = undefined;
_.each(valueSelector, function (value, selKey) {
var thisIsOperator = selKey.substr(0, 1) === '$';
if (theseAreOperators === undefined) {
theseAreOperators = thisIsOperator;
} else if (theseAreOperators !== thisIsOperator) {
if (!inconsistentOK)
throw new Error("Inconsistent operator: " +
JSON.stringify(valueSelector));
theseAreOperators = false;
}
});
return !!theseAreOperators; // {} has no operators
};
// string can be converted to integer
isNumericKey = function (s) {
return /^[0-9]+$/.test(s);
};