Skip to content

Commit d8c3342

Browse files
committed
Initial drop of code extracted from express-state
1 parent 57cebad commit d8c3342

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

LICENSE

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright 2014 Yahoo! Inc.
2+
All rights reserved.
3+
4+
Redistribution and use in source and binary forms, with or without
5+
modification, are permitted provided that the following conditions are met:
6+
7+
* Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
10+
* Redistributions in binary form must reproduce the above copyright
11+
notice, this list of conditions and the following disclaimer in the
12+
documentation and/or other materials provided with the distribution.
13+
14+
* Neither the name of the Yahoo! Inc. nor the
15+
names of its contributors may be used to endorse or promote products
16+
derived from this software without specific prior written permission.
17+
18+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
DISCLAIMED. IN NO EVENT SHALL YAHOO! INC. BE LIABLE FOR ANY
22+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

index.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
Copyright (c) 2014, Yahoo! Inc. All rights reserved.
3+
Copyrights licensed under the New BSD License.
4+
See the accompanying LICENSE file for terms.
5+
*/
6+
7+
'use strict';
8+
9+
var util = require('util');
10+
11+
module.exports = serialize;
12+
13+
var IS_NATIVE_CODE_REGEX = /\{\s*\[native code\]\s*\}/g,
14+
PLACE_HOLDER_REGEX = /"@__(FUNCTION|REGEXP)_(\d+)__@"/g,
15+
UNSAFE_CHARS_REGEX = /[<>\/\u2028\u2029]/g;
16+
17+
// Mapping of unsafe HTML and invalid JavaScript line terminator chars to their
18+
// Unicode char counterparts which are safe to use in JavaScript strings.
19+
var UNICODE_CHARS = {
20+
'<' : '\\u003C',
21+
'>' : '\\u003E',
22+
'/' : '\\u002F',
23+
'\u2028': '\\u2028',
24+
'\u2029': '\\u2029'
25+
};
26+
27+
function serialize(obj) {
28+
var functions = [],
29+
regexps = [],
30+
str;
31+
32+
// Creates a JSON string representation of the object and uses placeholders
33+
// for functions and regexps (identified by index) which are later
34+
// replaced.
35+
str = JSON.stringify(obj, function (key, value) {
36+
if (typeof value === 'function') {
37+
return '@__FUNCTION_' + (functions.push(value) - 1) + '__@';
38+
}
39+
40+
if (util.isRegExp(value)) {
41+
return '@__REGEXP_' + (regexps.push(value) - 1) + '__@';
42+
}
43+
44+
return value;
45+
});
46+
47+
// Protects against `JSON.stringify()` returning `undefined`, by serializing
48+
// to the literal string: "undefined".
49+
if (typeof str !== 'string') {
50+
return String(str);
51+
}
52+
53+
// Replace unsafe HTML and invalid JavaScript line terminator chars with
54+
// their safe Unicode char counterpart. This _must_ happen before the
55+
// regexps and functions are serialized and added back to the string.
56+
str = str.replace(UNSAFE_CHARS_REGEX, function (unsafeChar) {
57+
return UNICODE_CHARS[unsafeChar];
58+
});
59+
60+
if (!(functions.length || regexps.length)) {
61+
return str;
62+
}
63+
64+
// Replaces all occurrences of function and regexp placeholders in the JSON
65+
// string with their string representations. If the original value can not
66+
// be found, then `undefined` is used.
67+
return str.replace(PLACE_HOLDER_REGEX, function (match, type, index) {
68+
if (type === 'REGEXP') {
69+
return regexps[index].toString();
70+
}
71+
72+
var fn = functions[index],
73+
serializedFn = fn.toString();
74+
75+
if (IS_NATIVE_CODE_REGEX.test(serializedFn)) {
76+
throw new TypeError('Serializing native function: ' + fn.name);
77+
}
78+
79+
return serializedFn;
80+
});
81+
}

0 commit comments

Comments
 (0)