allow serializing of objects with null prototype

This commit is contained in:
Tobias Koppers 2018-12-25 22:07:51 +01:00
parent ce95525017
commit 44663f8c67
5 changed files with 58 additions and 2 deletions

View File

@ -0,0 +1,33 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
"use strict";
class NullPrototypeObjectSerializer {
serialize(obj, { write }) {
const keys = Object.keys(obj);
for (const key of keys) {
write(key);
}
write(null);
for (const key of keys) {
write(obj[key]);
}
}
deserialize({ read }) {
const obj = Object.create(null);
const keys = [];
let key = read();
while (key !== null) {
keys.push(key);
key = read();
}
for (const key of keys) {
obj[key] = read();
}
return obj;
}
}
module.exports = NullPrototypeObjectSerializer;

View File

@ -7,6 +7,7 @@
const memorize = require("../util/memorize");
const ErrorObjectSerializer = require("./ErrorObjectSerializer");
const MapObjectSerializer = require("./MapObjectSerializer");
const NullPrototypeObjectSerializer = require("./NullPrototypeObjectSerializer");
const PlainObjectSerializer = require("./PlainObjectSerializer");
const RegExpObjectSerializer = require("./RegExpObjectSerializer");
const SerializerMiddleware = require("./SerializerMiddleware");
@ -75,7 +76,7 @@ const ESCAPE_ESCAPE_VALUE = null;
const ESCAPE_END_OBJECT = true;
const ESCAPE_UNDEFINED = false;
const CURRENT_VERSION = 1;
const CURRENT_VERSION = 2;
const plainObjectSerializer = new PlainObjectSerializer();
@ -99,6 +100,7 @@ serializers.set(Array, {
});
const jsTypes = new Map();
jsTypes.set(null, new NullPrototypeObjectSerializer());
jsTypes.set(Map, new MapObjectSerializer());
jsTypes.set(Set, new SetObjectSerializer());
jsTypes.set(RegExp, new RegExpObjectSerializer());
@ -187,7 +189,17 @@ class ObjectMiddleware extends SerializerMiddleware {
}
static getSerializerFor(object) {
const c = object.constructor;
let c = object.constructor;
if (!c) {
if (Object.getPrototypeOf(object) === null) {
// Object created with Object.create(null)
c = null;
} else {
throw new Error(
"Serialization of objects with prototype without valid constructor property not possible"
);
}
}
const config = serializers.get(c);
if (!config) throw new Error(`No serializer registered for ${c.name}`);

View File

@ -0,0 +1 @@
module.exports = "ok";

View File

@ -0,0 +1,6 @@
import "./loader!./file";
it("should have the file emitted", () => {
const result = __non_webpack_require__("./extra-file.js");
expect(result).toBe("ok");
});

View File

@ -0,0 +1,4 @@
module.exports = function(content) {
this.emitFile("extra-file.js", content);
return "";
}