Skip to content

Commit e2dee42

Browse files
committed
Ensure unique cache keys, allow NUL characters
1 parent 3c83583 commit e2dee42

File tree

1 file changed

+82
-82
lines changed

1 file changed

+82
-82
lines changed

src/index.mjs

Lines changed: 82 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
const CACHE = {};
1515

1616
export default function html(statics) {
17-
const str = statics.join('\0');
18-
const tpl = CACHE[str] || (CACHE[str] = build(str));
17+
const key = statics.reduce((key, s) => key + s.length + '$' + s, '');
18+
const tpl = CACHE[key] || (CACHE[key] = build(statics));
1919
// eslint-disable-next-line prefer-rest-params
2020
return tpl(this, arguments);
2121
}
@@ -38,11 +38,10 @@ const MODE_ATTRIBUTE = 13;
3838
const MODE_SKIP = 47;
3939

4040
/** Create a template function given strings from a tagged template. */
41-
function build(input) {
41+
function build(statics) {
4242
let out = 'return ';
4343
let buffer = '';
4444
let mode = MODE_WHITESPACE;
45-
let fieldIndex = 1;
4645
let field = '';
4746
let hasChildren = 0;
4847
let props = '';
@@ -90,97 +89,98 @@ function build(input) {
9089
buffer = field = '';
9190
}
9291

93-
for (let i=0; i<input.length; i++) {
94-
charCode = input.charCodeAt(i);
95-
field = '';
96-
97-
if (charCode === QUOTE_SINGLE || charCode === QUOTE_DOUBLE) {
98-
if (quote === charCode) {
99-
quote = 0;
100-
continue;
101-
}
102-
if (quote === 0) {
103-
quote = charCode;
104-
continue;
105-
}
106-
}
107-
108-
if (charCode === 0) {
92+
for (let i=0; i<statics.length; i++) {
93+
if (i > 0) {
10994
if (!inTag) commit();
110-
field = `$_h[${fieldIndex++}]`;
95+
field = `$_h[${i}]`;
11196
commit();
112-
continue;
11397
}
98+
99+
const input = statics[i];
100+
for (let j=0; j<input.length; j++) {
101+
charCode = input.charCodeAt(j);
102+
field = '';
114103

115-
if (quote === 0) {
116-
switch (charCode) {
117-
case TAG_START:
118-
if (!inTag) {
119-
// commit buffer
120-
commit();
121-
inTag = true;
122-
props = '';
123-
slash = spread = propHasValue = false;
124-
mode = MODE_TAGNAME;
125-
continue;
126-
}
127-
128-
case TAG_END:
129-
if (inTag) {
130-
commit();
131-
if (mode !== MODE_SKIP) {
132-
if (!props) {
133-
out += ',null';
104+
if (charCode === QUOTE_SINGLE || charCode === QUOTE_DOUBLE) {
105+
if (quote === charCode) {
106+
quote = 0;
107+
continue;
108+
}
109+
if (quote === 0) {
110+
quote = charCode;
111+
continue;
112+
}
113+
}
114+
115+
if (quote === 0) {
116+
switch (charCode) {
117+
case TAG_START:
118+
if (!inTag) {
119+
// commit buffer
120+
commit();
121+
inTag = true;
122+
props = '';
123+
slash = spread = propHasValue = false;
124+
mode = MODE_TAGNAME;
125+
continue;
126+
}
127+
128+
case TAG_END:
129+
if (inTag) {
130+
commit();
131+
if (mode !== MODE_SKIP) {
132+
if (!props) {
133+
out += ',null';
134+
}
135+
else {
136+
out += ',' + props + '}' + (spread ? ')' : '');
137+
}
134138
}
135-
else {
136-
out += ',' + props + '}' + (spread ? ')' : '');
139+
if (slash) {
140+
out += ')';
137141
}
142+
spread = inTag = false;
143+
props = '';
144+
mode = MODE_TEXT;
145+
continue;
138146
}
139-
if (slash) {
140-
out += ')';
147+
148+
case EQUALS:
149+
if (inTag) {
150+
mode = MODE_ATTRIBUTE;
151+
propHasValue = true;
152+
propName = buffer;
153+
buffer = '';
154+
continue;
141155
}
142-
spread = inTag = false;
143-
props = '';
144-
mode = MODE_TEXT;
145-
continue;
146-
}
147-
148-
case EQUALS:
149-
if (inTag) {
150-
mode = MODE_ATTRIBUTE;
151-
propHasValue = true;
152-
propName = buffer;
153-
buffer = '';
154-
continue;
155-
}
156156

157-
case SLASH:
158-
if (inTag) {
159-
if (!slash) {
160-
slash = true;
161-
// </foo>
162-
if (mode === MODE_TAGNAME && !field && !buffer.trim().length) {
163-
buffer = field = '';
164-
mode = MODE_SKIP;
157+
case SLASH:
158+
if (inTag) {
159+
if (!slash) {
160+
slash = true;
161+
// </foo>
162+
if (mode === MODE_TAGNAME && !field && !buffer.trim().length) {
163+
buffer = field = '';
164+
mode = MODE_SKIP;
165+
}
165166
}
167+
continue;
168+
}
169+
case TAB:
170+
case NEWLINE:
171+
case RETURN:
172+
case SPACE:
173+
// <a disabled>
174+
if (inTag) {
175+
commit();
176+
mode = MODE_WHITESPACE;
177+
continue;
166178
}
167-
continue;
168-
}
169-
case TAB:
170-
case NEWLINE:
171-
case RETURN:
172-
case SPACE:
173-
// <a disabled>
174-
if (inTag) {
175-
commit();
176-
mode = MODE_WHITESPACE;
177-
continue;
178-
}
179+
}
179180
}
180-
}
181-
182-
buffer += input.charAt(i);
183181

182+
buffer += input.charAt(j);
183+
}
184184
}
185185
commit();
186186
return Function('h', '$_h', out);

0 commit comments

Comments
 (0)