mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
fix: stack exceeding for css tokenizer (#1862)
* fix: stack exceeding for css tokenizer * fix: token string recursion
This commit is contained in:
parent
cae44a6f0a
commit
cbaecdca28
@ -316,7 +316,7 @@ export class Tokenizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
write(chunk: string) {
|
write(chunk: string) {
|
||||||
this._value.push(...toCodePoints(chunk));
|
this._value = this._value.concat(toCodePoints(chunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
read(): CSSToken[] {
|
read(): CSSToken[] {
|
||||||
@ -370,7 +370,6 @@ export class Tokenizer {
|
|||||||
return this.consumeNumericToken();
|
return this.consumeNumericToken();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
break;
|
|
||||||
case COMMA:
|
case COMMA:
|
||||||
return COMMA_TOKEN;
|
return COMMA_TOKEN;
|
||||||
case HYPHEN_MINUS:
|
case HYPHEN_MINUS:
|
||||||
@ -472,7 +471,6 @@ export class Tokenizer {
|
|||||||
}
|
}
|
||||||
this.reconsumeCodePoint(codePoint);
|
this.reconsumeCodePoint(codePoint);
|
||||||
return this.consumeIdentLikeToken();
|
return this.consumeIdentLikeToken();
|
||||||
break;
|
|
||||||
case VERTICAL_LINE:
|
case VERTICAL_LINE:
|
||||||
if (this.peekCodePoint(0) === EQUALS_SIGN) {
|
if (this.peekCodePoint(0) === EQUALS_SIGN) {
|
||||||
this.consumeCodePoint();
|
this.consumeCodePoint();
|
||||||
@ -655,32 +653,51 @@ export class Tokenizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private consumeStringSlice(count: number): string {
|
||||||
|
const SLICE_STACK_SIZE = 60000;
|
||||||
|
let value = '';
|
||||||
|
while (count > 0) {
|
||||||
|
const amount = Math.min(SLICE_STACK_SIZE, count);
|
||||||
|
value += fromCodePoint(...this._value.splice(0, amount));
|
||||||
|
count -= amount;
|
||||||
|
}
|
||||||
|
this._value.shift();
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
private consumeStringToken(endingCodePoint: number): StringValueToken | Token {
|
private consumeStringToken(endingCodePoint: number): StringValueToken | Token {
|
||||||
let value = '';
|
let value = '';
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
const codePoint = this.consumeCodePoint();
|
const codePoint = this._value[i];
|
||||||
if (codePoint === EOF || codePoint === endingCodePoint) {
|
if (codePoint === EOF || codePoint === undefined || codePoint === endingCodePoint) {
|
||||||
|
value += this.consumeStringSlice(i);
|
||||||
return {type: TokenType.STRING_TOKEN, value};
|
return {type: TokenType.STRING_TOKEN, value};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codePoint === LINE_FEED) {
|
if (codePoint === LINE_FEED) {
|
||||||
this.reconsumeCodePoint(codePoint);
|
this._value.splice(0, i);
|
||||||
return BAD_STRING_TOKEN;
|
return BAD_STRING_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (codePoint === REVERSE_SOLIDUS) {
|
if (codePoint === REVERSE_SOLIDUS) {
|
||||||
const next = this.peekCodePoint(0);
|
const next = this._value[i + 1];
|
||||||
if (next !== EOF) {
|
if (next !== EOF && next !== undefined) {
|
||||||
if (next === LINE_FEED) {
|
if (next === LINE_FEED) {
|
||||||
this.consumeCodePoint();
|
value += this.consumeStringSlice(i);
|
||||||
|
i = -1;
|
||||||
|
this._value.shift();
|
||||||
} else if (isValidEscape(codePoint, next)) {
|
} else if (isValidEscape(codePoint, next)) {
|
||||||
|
value += this.consumeStringSlice(i);
|
||||||
value += fromCodePoint(this.consumeEscapedCodePoint());
|
value += fromCodePoint(this.consumeEscapedCodePoint());
|
||||||
|
i = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
value += fromCodePoint(codePoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user