Fix sig solving for tce and es6 player variants (#47)

This commit is contained in:
Simon Sawicki
2026-02-21 17:32:45 +01:00
committed by GitHub
parent 1b648c34c1
commit 5bc9811c7a
4 changed files with 253 additions and 55 deletions

View File

@@ -380,11 +380,11 @@ jobs:
name: player-js
- name: Run Deno tests
run: |
xargs -n 1 -P 8 deno test \
xargs -n 1 -P 10 deno test \
--no-prompt \
--no-check \
--allow-read=src/yt/solver/test/players/ \
--filter <<<"$(printf -- ' %s \n' main tcc tce es5 es6 tv tv_es6 phone)"
--filter <<<"$(printf -- '-%s-\n' main tcc tce es5 es6 tv tv_es6 phone es6_tcc es6_tce)"
bun_build:
name: Test Bun build

View File

@@ -2,33 +2,34 @@ import { type ESTree } from "meriyah";
import { matchesStructure } from "../../utils.ts";
import { type DeepPartial } from "../../types.ts";
const nsigExpression: DeepPartial<ESTree.Statement> = {
type: "VariableDeclaration",
kind: "var",
declarations: [
const nsig: DeepPartial<ESTree.CallExpression> = {
type: "CallExpression",
callee: {
or: [{ type: "Identifier" }, { type: "SequenceExpression" }],
},
arguments: [
{},
{
type: "VariableDeclarator",
init: {
type: "CallExpression",
callee: {
type: "Identifier",
},
arguments: [
{
type: "Literal",
},
{
type: "CallExpression",
callee: {
type: "Identifier",
name: "decodeURIComponent",
},
},
],
type: "CallExpression",
callee: {
type: "Identifier",
name: "decodeURIComponent",
},
arguments: [{}],
},
],
};
const nsigAssignment: DeepPartial<ESTree.AssignmentExpression> = {
type: "AssignmentExpression",
left: { type: "Identifier" },
operator: "=",
right: nsig,
};
const nsigDeclarator: DeepPartial<ESTree.VariableDeclarator> = {
type: "VariableDeclarator",
id: { type: "Identifier" },
init: nsig,
};
const logicalExpression: DeepPartial<ESTree.ExpressionStatement> = {
type: "ExpressionStatement",
@@ -53,6 +54,17 @@ const logicalExpression: DeepPartial<ESTree.ExpressionStatement> = {
},
arguments: {
or: [
[
{
type: "CallExpression",
callee: {
type: "Identifier",
name: "decodeURIComponent",
},
arguments: [{ type: "Identifier" }],
optional: false,
},
],
[
{ type: "Literal" },
{
@@ -66,6 +78,8 @@ const logicalExpression: DeepPartial<ESTree.ExpressionStatement> = {
},
],
[
{ type: "Literal" },
{ type: "Literal" },
{
type: "CallExpression",
callee: {
@@ -98,17 +112,15 @@ const identifier: DeepPartial<ESTree.Node> = {
type: "AssignmentExpression",
operator: "=",
left: {
type: "Identifier",
or: [{ type: "Identifier" }, { type: "MemberExpression" }],
},
right: {
type: "FunctionExpression",
params: [{}, {}, {}],
},
},
},
{
type: "FunctionDeclaration",
params: [{}, {}, {}],
},
{
type: "VariableDeclaration",
@@ -118,7 +130,6 @@ const identifier: DeepPartial<ESTree.Node> = {
type: "VariableDeclarator",
init: {
type: "FunctionExpression",
params: [{}, {}, {}],
},
},
],
@@ -137,22 +148,19 @@ export function extract(
node.type === "ExpressionStatement" &&
node.expression.type === "AssignmentExpression" &&
node.expression.right.type === "FunctionExpression" &&
node.expression.right.params.length === 3
node.expression.right.params.length >= 3
) {
blocks.push(node.expression.right.body!);
} else if (node.type === "VariableDeclaration") {
for (const decl of node.declarations) {
if (
decl.init?.type === "FunctionExpression" &&
decl.init.params.length === 3
decl.init.params.length >= 3
) {
blocks.push(decl.init.body!);
}
}
} else if (
node.type === "FunctionDeclaration" &&
node.params.length === 3
) {
} else if (node.type === "FunctionDeclaration" && node.params.length >= 3) {
blocks.push(node.body!);
} else {
return null;
@@ -179,6 +187,7 @@ export function extract(
for (const stmt of block.body) {
if (matchesStructure(stmt, logicalExpression)) {
// legacy matching
if (
stmt.type === "ExpressionStatement" &&
stmt.expression.type === "LogicalExpression" &&
@@ -188,34 +197,61 @@ export function extract(
stmt.expression.right.expressions[0].right.type === "CallExpression"
) {
call = stmt.expression.right.expressions[0].right;
break;
}
} else if (stmt.type === "IfStatement") {
// if (...) { var a, b = (0, c)(1, decodeURIComponent(...))}
let consequent = stmt.consequent;
while (consequent.type === "LabeledStatement") {
consequent = consequent.body;
}
if (consequent.type !== "BlockStatement") {
continue;
}
if (consequent.type === "BlockStatement") {
for (const n of consequent.body) {
if (!matchesStructure(n, nsigExpression)) {
continue;
}
for (const n of consequent.body) {
if (n.type !== "VariableDeclaration") {
continue;
}
for (const decl of n.declarations) {
if (
n.type === "VariableDeclaration" &&
n.declarations[0]?.init?.type === "CallExpression"
matchesStructure(decl, nsigDeclarator) &&
decl.init?.type === "CallExpression"
) {
call = n.declarations[0].init;
call = decl.init;
break;
}
}
if (call) {
break;
}
}
} else if (stmt.type === "ExpressionStatement") {
// (...) && ((...), (c = (...)(decodeURIComponent(...))))
if (
stmt.expression.type !== "LogicalExpression" ||
stmt.expression.operator !== "&&" ||
stmt.expression.right.type !== "SequenceExpression"
) {
continue;
}
for (const expr of stmt.expression.right.expressions) {
if (matchesStructure(expr, nsigAssignment) && expr.type) {
if (
expr.type === "AssignmentExpression" &&
expr.right.type === "CallExpression"
) {
call = expr.right;
break;
}
}
}
if (call) break;
}
if (call) {
break;
}
}
if (call?.callee.type !== "Identifier") {
if (!call) {
continue;
}
@@ -230,16 +266,12 @@ export function extract(
],
body: {
type: "CallExpression",
callee: {
type: "Identifier",
name: call.callee.name,
},
callee: call.callee,
arguments: call.arguments.map((arg): ESTree.Expression => {
if (
arg.type === "CallExpression" &&
arg.callee.type === "Identifier" &&
arg.callee.name === "decodeURIComponent" &&
arg.arguments[0]?.type === "Identifier"
arg.callee.name === "decodeURIComponent"
) {
return { type: "Identifier", name: "sig" };
}

View File

@@ -8,7 +8,7 @@ const io = await getIO();
for (const test of tests) {
for (const variant of test.variants ?? players.keys()) {
const path = getCachePath(test.player, variant);
await io.test(` ${test.player} ${variant} `, async (assert, subtest) => {
await io.test(`-${test.player}-${variant}-`, async (assert, subtest) => {
const content = await io.read(path);
const solvers = getFromPrepared(preprocessPlayer(content));
for (const mode of ["n", "sig"] as const) {

View File

@@ -286,8 +286,6 @@ export const tests: {
{
// tce variant broke sig solving; n and other variants are added only for regression testing
player: "c1c87fb0",
// TODO: fix other variants in other PR
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone"],
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "jCHBK5GuAFNa2" },
@@ -319,6 +317,172 @@ export const tests: {
},
],
},
{
// sig: tce: deep if: multiple matching but giving same solution
player: "42c5570b",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "CRoXjB-R-R" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"EN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavcOmNdYN-wUtgEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
},
],
},
{
// sig: tce: deep if
player: "ed3f6ea5",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "CRoXjB-R-R" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"EN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavcOmNdYN-wUtgEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
},
],
},
{
// sig: tce: deep if: another, similar structure using && instead of if
player: "d6afc319",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "5RA1UjcYMe33HCQ" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXt2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtS",
},
],
},
{
// sig: tce: deep if
player: "8da75a6a",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "Q3JvBQziA7PvI" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"g7aNhudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyJxCBGgIARwsSdQfJ2CZ",
},
],
},
{
// sig: tce: call with 3 parameters
player: "54bd1de4",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "ka-slAQ31sijFN" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0titeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtp",
},
],
},
{
// sig: tce: call with 3 parameters
player: "f104ea90",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "n5DnuOYzgrSUbWp" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"fJC2JtQdSswRAIgGBCxZyAfKyi0cjXCb3DqEctUw-NYdNmOEZaepit0z7AtIEsgOV2SX-jhSHMNy0NXNG_1kOyBf6HPuAuCduhv",
},
],
},
{
// sig: tce: call with 3 parameters
player: "3510b6ff",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "n5DnuOYzgrSUbWp" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"fJC2JtQdSswRAIgGBCxZyAfKyi0cjXCb3DqEctUw-NYdNmOEZaepit0z7AtIEsgOV2SX-jhSHMNy0NXNG_1kOyBf6HPuAuCduhv",
},
],
},
{
// sig: tce: call with 3 parameters
player: "0675bd00",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "n5DnuOYzgrSUbWp" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"fJC2JtQdSswRAIgGBCxZyAfKyi0cjXCb3DqEctUw-NYdNmOEZaepit0z7AtIEsgOV2SX-jhSHMNy0NXNG_1kOyBf6HPuAuCduhv",
},
],
},
{
// sig: tce: call with 3 parameters
player: "e0528946",
n: [
// Synthetic test
{ input: "ZdZIqFPQK-Ty8wId", expected: "cGKEGBME8PGi7z" },
],
sig: [
// Synthetic test
{
input:
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
expected:
"7a-hudCuAuPH6fByOk1_GNXN0yNMgShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2C",
},
],
},
{
// sig: es6: call with 3 parameters
player: "94667337",
n: [{ input: "BQoJvGBkC2nj1ZZLK-", expected: "ib1ShEOGoFXIIw" }],
sig: [
{
input:
"NJAJEij0EwRgIhAI0KExTgjfPk-MPM9MAdzyyPRt=BM8-XO5tm5hlMCSVpAiEAv7eP3CURqZNSPow8BXXAoazVoXgeMP7gH9BdylHCwgw=gwzz",
expected:
"AJEij0EwRgIhAI0KExTgjfPk-MPM9MNdzyyPRtzBM8-XO5tm5hlMCSVpAiEAv7eP3CURqZNSPow8BXXAoazVoXgeMP7gH9BdylHCwgw=",
},
],
},
];
export const players = new Map([
@@ -330,6 +494,8 @@ export const players = new Map([
["tv", "tv-player-ias.vflset/tv-player-ias.js"],
["tv_es6", "tv-player-es6.vflset/tv-player-es6.js"],
["phone", "player-plasma-ias-phone-en_US.vflset/base.js"],
["es6_tcc", "player_es6_tcc.vflset/en_US/base.js"],
["es6_tce", "player_es6_tce.vflset/en_US/base.js"],
] as const);
export type Variant = typeof players extends Map<infer T, unknown> ? T : never;