Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bidar

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bidar - npm Package Compare versions

Comparing version 0.2.1 to 0.2.2

108

lib/serial.js

@@ -108,22 +108,4 @@ // Copyright 2012 The Obvious Corporation.

var allRefs = oid.createMap();
var holeSet = allowHoles ? oid.createSet() : undefined;
var holes = allowHoles ? oid.createMap() : undefined;
/**
* Check to see if holes are currently being allowed. If not,
* complain appropriateley.
*/
function holeCheck() {
if (allowHoles) {
return;
} else if (type.isUndefined(holeFilter)) {
throw new Error("Hole-ful graph, but no hole filter.");
} else {
throw new Error("Holes not allowed in holes.");
}
}
function addHole(x) {
holeSet.add(x);
}
function nop() {

@@ -140,4 +122,4 @@ // This space intentionally left blank.

function addRef(obj, innerVisitor, mustBeHole) {
if (mustBeHole) {
holeCheck();
if (mustBeHole && !allowHoles) {
throw new Error("Hole-ful graph, but no hole filter.");
}

@@ -151,3 +133,11 @@

if (mustBeHole) {
addHole(obj);
var already = holes.get(obj);
if (!already) {
var replacement = holeFilter(obj);
if (replacement === obj) {
throw new Error("Bogus hole non-replacement.");
}
holes.set(obj, replacement);
iterate.iterate(replacement, visitor);
}
} else if (innerVisitor) {

@@ -165,6 +155,9 @@ innerVisitor();

if (Buffer.isBuffer(obj)) {
// Suppress inner visit for buffers.
// Suppress the inner visit for buffers, because it is too
// odious to imagine having to cons up all the keys for
// the buffer indices. (Too bad there's no
// `Object.getOwnNamedProperties()` or somesuch.)
addRef(obj, undefined);
} else {
addRef(obj, innerVisitor);
addRef(obj, innerVisitor, !type.isMap(obj));
}

@@ -193,19 +186,6 @@ }

var holes = undefined;
if (allowHoles) {
holes = oid.createMap();
allowHoles = false;
holeSet.forEach(function (obj) {
var replacement = holeFilter(obj);
holes.set(obj, replacement);
iterate.iterate(replacement, visitor);
});
}
var backRefs = oid.createSet();
allRefs.forEach(function (key, value) {
if (value > 1) {
backRefs.add(key);
allRefs.forEach(function (ref, count) {
if (count > 1) {
backRefs.add(ref);
}

@@ -316,16 +296,11 @@ });

function writeHole(obj) {
var replacement = holeMap.get(obj, obj);
if (replacement === obj) {
throw new Error("Missing replacement for hole.");
}
writeType(HOLE_DEF_TYPE);
iterate.iterate(replacement, visitor);
}
function handleBackRef(obj) {
/**
* Handle the cases where the given object is either a back-reference
* or an as-yet unwritten hole. Returns `true` if this function
* ended up writing out the value or `false` if not.
*/
function handleBackRefOrHole(obj) {
if (!backRefSet.has(obj)) {
// No multiple references for this value.
return false;
return handlePossibleHole(obj);
}

@@ -342,3 +317,3 @@

backRefCount++;
return false;
return handlePossibleHole(obj);
}

@@ -353,6 +328,21 @@

return true;
function handlePossibleHole(obj) {
if (!holeMap) {
return false;
}
var replacement = holeMap.get(obj, obj);
if (replacement === obj) {
return false;
}
writeType(HOLE_DEF_TYPE);
iterate.iterate(replacement, visitor);
return true;
}
}
function visitObject(obj, innerVisitor) {
if (handleBackRef(obj)) {
if (handleBackRefOrHole(obj)) {
// Nothing else to do.

@@ -372,3 +362,3 @@ return;

} else {
writeHole(obj);
throw new Error("Missing replacement for hole.");
}

@@ -395,3 +385,3 @@ }

function visitArray(arr, innerVisitor) {
if (handleBackRef(arr)) {
if (handleBackRefOrHole(arr)) {
// Nothing else to do.

@@ -421,4 +411,4 @@ return;

function visitFunction(func, innerVisitor) {
if (!handleBackRef(func)) {
writeHole(func);
if (!handleBackRefOrHole(func)) {
throw new Error("Missing replacement for hole.");
}

@@ -428,3 +418,3 @@ }

function visitString(str) {
if (handleBackRef(str)) {
if (handleBackRefOrHole(str)) {
// Nothing else to do.

@@ -431,0 +421,0 @@ return;

@@ -30,2 +30,5 @@ // Copyright 2012 The Obvious Corporation.

/** extended type name */
var DATE = "date";
/** type name */

@@ -38,2 +41,5 @@ var FUNCTION = "function";

/** extended type name */
var MAP = "map";
/** extended type name */
var NULL = "null";

@@ -56,3 +62,9 @@

/** the prototype of plain (map) objects */
var OBJECT_PROTOTYPE = Object.getPrototypeOf({});
/** the prototype of date objects */
var DATE_PROTOTYPE = Date.prototype;
/*

@@ -82,6 +94,10 @@ * Helper functions

return NULL;
} else if (Array.isArray(value)) {
} else if (isArray(value)) {
return ARRAY;
} else if (Buffer.isBuffer(value)) {
} else if (isBuffer(value)) {
return BUFFER;
} else if (isDate(value)) {
return DATE;
} else if (isMap(value)) {
return MAP;
} else {

@@ -103,2 +119,3 @@ return OBJECT;

case BOOLEAN:
case DATE:
case INT:

@@ -130,7 +147,11 @@ case NUMBER:

function isBoolean(x) {
return (x === true) || (x === false);
}
// For symmetry.
var isBuffer = Buffer.isBuffer;
function isBoolean(x) {
return (x === true) || (x === false);
function isDate(x) {
return Object.getPrototypeOf(x) === DATE_PROTOTYPE;
}

@@ -150,2 +171,22 @@

/**
* A "map" is an object whose prototype is the default object prototype
* and which furthermore defines no enumerable dynamic properties.
*/
function isMap(x) {
if (Object.getPrototypeOf(x) !== OBJECT_PROTOTYPE) {
return false;
}
var keys = Object.keys(x);
for (var i = 0; i < keys.length; i++) {
var props = Object.getOwnPropertyDescriptor(x, keys[i]);
if (props.get || props.set) {
return false;
}
}
return true;
}
function isNumber(x) {

@@ -198,2 +239,8 @@ return (typeof x) === NUMBER;

function assertDate(x) {
if (!isDate(x)) {
failType(x, DATE);
}
}
function assertDefined(x) {

@@ -224,2 +271,8 @@ if (!isDefined(x)) {

function assertMap(x) {
if (!isMap(x)) {
failType(x, MAP);
}
}
function assertString(x) {

@@ -254,2 +307,3 @@ if (!isString(x)) {

assertBuffer: assertBuffer,
assertDate: assertDate,
assertDefined: assertDefined,

@@ -259,2 +313,3 @@ assertFunction: assertFunction,

assertNumber: assertNumber,
assertMap: assertMap,
assertString: assertString,

@@ -266,2 +321,3 @@ assertUint: assertUint,

isBuffer: isBuffer,
isDate: isDate,
isDefined: isDefined,

@@ -271,2 +327,3 @@ isInt: isInt,

isNumber: isNumber,
isMap: isMap,
isString: isString,

@@ -273,0 +330,0 @@ isUint: isUint,

{
"name": "bidar",
"version": "0.2.1",
"version": "0.2.2",
"keywords":

@@ -5,0 +5,0 @@ ["object", "serialization", "data", "graph"],

@@ -155,9 +155,18 @@ Bidar: Binary Data Representation.

A "hole" is any object that is not representable as pure data. This
includes functions and (non-array, non-buffer) objects whose prototype
is not the default object prototype.
includes:
* functions
* non-array non-buffer objects whose prototype is not the default
object prototype
* objects that define any dynamic properties (getters or setters)
The hole filter is called with a single argument -- the original
"hole" object encountered in the graph -- and is expected to return a
serializable pure data object in response. That object is marked as
a "hole replacement" in the serialized output.
serializable replacement object in response. That object is marked as
a "hole replacement" in the serialized output. It is possible for a
hole replacement to itself have holes in it; this is fine, so long as
the hole replacer can successfully replace all the holes, eventually
bottoming out at pure data in some form.

@@ -258,3 +267,3 @@ ### parse(buf, [holeFiller])

times from an array inner visitor, and is always called before
`visitObjectBinding() is called for the named object bindings. The
`visitObjectBinding()` is called for the named object bindings. The
`missing` parameter (placed after `innerVisitor` both so that it

@@ -261,0 +270,0 @@ is easily ignored and so that the `innerVisitor` is always the

@@ -314,3 +314,6 @@ // Copyright 2012 The Obvious Corporation.

function testSimpleHole() {
/**
* Test top-level hole replacement, where the hole is a function.
*/
function testSimpleHole_function() {
var serialized = bidar.serialize(theHole, holeFilter);

@@ -340,2 +343,55 @@ var parsed = bidar.parse(serialized, holeFiller);

/**
* Test top-level hole replacement, where the hole is an object with
* a non-default prototype.
*/
function testSimpleHole_prototype() {
var theHole = Object.create({ x: "in proto" });
var theReplacement = "yay";
var serialized = bidar.serialize(theHole, holeFilter);
var parsed = bidar.parse(serialized, holeFiller);
assert.equal(parsed, theReplacement);
function holeFilter(x) {
assert.equal(x, theHole);
return "blort";
}
function holeFiller(x) {
assert.equal(x, "blort");
return theReplacement;
}
}
/**
* Test top-level hole replacement, where the hole is an object with
* a dynamic property binding.
*/
function testSimpleHole_dynamic() {
roundTrip({ get foo() { return 1; } }, "one");
roundTrip({ set foo(value) { /*empty*/ } }, "two");
roundTrip({
get bar() { return 1; },
set bar(value) { /*empty*/ }
});
function roundTrip(theHole, theReplacement) {
var serialized = bidar.serialize(theHole, holeFilter);
var parsed = bidar.parse(serialized, holeFiller);
assert.equal(parsed, theReplacement);
function holeFilter(x) {
assert.equal(x, theHole);
return "blort";
}
function holeFiller(x) {
assert.equal(x, "blort");
return theReplacement;
}
}
}
function testInnerHole() {

@@ -369,3 +425,6 @@ var obj = { x: hole1, y: hole2, z: [ hole1, hole2, "stuff" ] };

function test_fail_hole() {
/**
* Test hole replacement failures, when the hole is a function.
*/
function test_fail_hole_function() {
var obj = { a: hole };

@@ -382,2 +441,3 @@

// This is an attempt to replace a would-be hole with itself.
function f2() {

@@ -387,19 +447,50 @@ bidar.serialize(obj, filter);

function filter(x) {
// An arbitrary-but-different hole.
return filter;
// The same hole.
return x;
}
}
assert.throws(f2, /Holes not allowed in holes/);
assert.throws(f2, /Bogus hole non-replacement/);
function f3() {
// This is a case where the first layer replacement is okay, but
// the second is a circular reference.
function f2() {
bidar.serialize(obj, filter);
function filter(x) {
// The same hole.
return x;
// An arbitrary-but-different hole.
return filter;
}
}
assert.throws(f3, /Holes not allowed in holes/);
assert.throws(f2, /Bogus hole non-replacement/);
}
/**
* Test hole replacement failure, when the hole is an object with a
* non-default prototype.
*/
function test_fail_hole_prototype() {
var obj = Object.create({ stuff: "in prototype" });
obj.foo = "bar";
function f1() {
bidar.serialize(obj);
}
assert.throws(f1, /Hole-ful graph, but no hole filter/);
}
/**
* Test hole replacement failure, when the hole is an object with a
* dynamic binding.
*/
function test_fail_hole_dynamic() {
var obj = {
get x() { return 10; }
};
function f1() {
bidar.serialize(obj);
}
assert.throws(f1, /Hole-ful graph, but no hole filter/);
}
function testLargeString() {

@@ -484,5 +575,9 @@ var string1 = "abcdefg1234567890---THIS IS YOUR CAPTAIN SPEAKING---" +

testCircularObject();
testSimpleHole();
testSimpleHole_function();
testSimpleHole_prototype();
testSimpleHole_dynamic();
testInnerHole();
test_fail_hole();
test_fail_hole_function();
test_fail_hole_prototype();
test_fail_hole_dynamic();
testLargeString();

@@ -489,0 +584,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc