执行 Ruff 安全自动修复

This commit is contained in:
yml2213
2026-08-31 10:28:14 +08:00
parent 2a1d27f953
commit b58c6b4357
145 changed files with 940 additions and 993 deletions
+8 -7
View File
@@ -34,19 +34,20 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parent
sys.path.insert(0, str(ROOT))
from pyvm.algorithm import build_plaintext, generate_encrypt_msg_offline # noqa: E402
from pyvm.mall import MallSession, generate_encrypt_msg as mall_generate # noqa: E402
from pyvm.session import SessionState, load_session # noqa: E402
from pyvm.login_profile import midas_login_params # noqa: E402
from pyvm.payment_errors import describe_payment_failure # noqa: E402
from pyvm.protocol import ( # noqa: E402
from pyvm.algorithm import generate_encrypt_msg_offline
from pyvm.login_profile import midas_login_params
from pyvm.mall import MallSession
from pyvm.mall import generate_encrypt_msg as mall_generate
from pyvm.payment_errors import describe_payment_failure
from pyvm.protocol import (
GOODS_USER_AGENT,
MALL_API_URL,
MALL_USER_AGENT,
GOODS_USER_AGENT,
PAY_APPID,
validate_goods_materials,
validate_mall_materials,
)
from pyvm.session import SessionState, load_session
REPLAY = ROOT / "replay"
DEFAULT_APPID = PAY_APPID
+10 -8
View File
@@ -13,22 +13,24 @@ from .algorithm import (
generate_encrypt_msg,
generate_encrypt_msg_offline,
)
from .goods import GoodsSession, generate_encrypt_msg as goods_generate
from .mall import MallSession, generate_encrypt_msg as mall_generate
from .goods import GoodsSession
from .goods import generate_encrypt_msg as goods_generate
from .mall import MallSession
from .mall import generate_encrypt_msg as mall_generate
from .pagedoo_vm import PagedooVM, run_frame
from .session import SessionState, load_session
__all__ = [
"GoodsSession",
"MallSession",
"PagedooVM",
"SessionState",
"build_plaintext",
"decode_d",
"generate_encrypt_msg",
"generate_encrypt_msg_offline",
"GoodsSession",
"goods_generate",
"MallSession",
"mall_generate",
"PagedooVM",
"run_frame",
"SessionState",
"load_session",
"mall_generate",
"run_frame",
]
@@ -13,6 +13,7 @@
"""
from __future__ import annotations
import itertools
import json
import math
@@ -355,7 +356,7 @@ def js_set(obj, key, val):
if isinstance(obj, str):
raise TypeError("Cannot assign to read only property")
cur = getattr(
getattr(__import__("pyvm.algorithm", fromlist=["x"]), "VM"), "_last_u", None
__import__("pyvm.algorithm", fromlist=["x"]).VM, "_last_u", None
)
raise TypeError(
f"invalid set target obj={type(obj).__name__} key={key!r} val={type(val).__name__} u={cur}"
@@ -418,7 +419,7 @@ class Window:
class JSFunction:
"""VM 函数(解释器实例工厂返回的 h)。"""
__slots__ = ("entry", "args", "s", "n", "t", "vm", "name")
__slots__ = ("args", "entry", "n", "name", "s", "t", "vm")
def __init__(self, vm, entry, args, s, n, t):
self.vm = vm
@@ -455,7 +456,7 @@ def js_call(fn, this, args):
return fn.fn(this, *args)
if callable(fn):
return fn(this, *args)
raise TypeError(f"{str(fn)} is not a function u={getattr(VM, '_last_u', None)}")
raise TypeError(f"{fn!s} is not a function u={getattr(VM, '_last_u', None)}")
def js_apply(fn, this, args):
+2 -3
View File
@@ -12,7 +12,6 @@ from __future__ import annotations
import json
from pathlib import Path
from typing import Any
from .algorithm import generate_encrypt_msg_offline
@@ -64,7 +63,7 @@ class GoodsSession:
raise ValueError("key16/key1 应为 16 字节")
@classmethod
def from_session_state(cls, path: str | Path) -> "GoodsSession":
def from_session_state(cls, path: str | Path) -> GoodsSession:
"""从 scripts/capture-session.mjs 生成的 session-state.json 加载。"""
d = json.loads(Path(path).read_text(encoding="utf-8"))
return cls(
@@ -85,7 +84,7 @@ class GoodsSession:
}
@classmethod
def from_json(cls, d: dict) -> "GoodsSession":
def from_json(cls, d: dict) -> GoodsSession:
return cls(
d["xmidas_ops"],
d["key16"],
+2 -3
View File
@@ -19,7 +19,6 @@ import copy
import json
import re
from pathlib import Path
from typing import Any
from .algorithm import UNDEF, JSObject, Window
from .pagedoo_vm import PagedooVM
@@ -78,7 +77,7 @@ class MallSession:
raise ValueError(f"624B 中间态长度 != 624: {len(mid[0])}")
@classmethod
def from_capture_file(cls, frames_jsonl: str | Path) -> "MallSession":
def from_capture_file(cls, frames_jsonl: str | Path) -> MallSession:
"""从捕获的 frames.jsonl 提取同会话 transform_input + xMidasOps。
frames.jsonl 由 scripts/capture-mall-session.mjs 实时落盘:
@@ -127,7 +126,7 @@ class MallSession:
}
@classmethod
def from_json(cls, d: dict) -> "MallSession":
def from_json(cls, d: dict) -> MallSession:
return cls(d["transform_input"], d["xmidas_ops"])
+34 -39
View File
@@ -13,56 +13,51 @@ JS 语义辅助复用 algorithm.py(_ic/i32/js_add/js_index/JSObject/JSFunction
from __future__ import annotations
import json
import math
import urllib.parse
from pathlib import Path
from .algorithm import (
JSDate,
UNDEF,
HostFunction,
JSDate,
JSFunction,
JSObject,
HostFunction,
_ic,
i32,
u32,
ushr,
shl,
shr,
js_typeof,
js_truthy,
js_str,
js_add,
js_num,
js_eq,
js_streq,
js_index,
js_set,
js_del,
js_keys,
js_call,
js_apply,
js_new,
h_math_floor,
h_math_round,
h_math_ceil,
h_math_min,
h_math_max,
h_math_abs,
h_math_pow,
h_math_sqrt,
h_parseint,
h_parsefloat,
h_isnan,
h_encodeuri,
h_encodeuricomponent,
h_decodeuri,
h_decodeuricomponent,
h_string_fromcharcode,
h_encodeuri,
h_encodeuricomponent,
h_isnan,
h_math_abs,
h_math_ceil,
h_math_floor,
h_math_max,
h_math_min,
h_math_pow,
h_math_round,
h_math_sqrt,
h_new_date,
h_parsefloat,
h_parseint,
h_string_fromcharcode,
i32,
js_add,
js_apply,
js_call,
js_del,
js_eq,
js_index,
js_keys,
js_new,
js_num,
js_set,
js_str,
js_truthy,
js_typeof,
shl,
shr,
ushr,
)
__all__ = ["PagedooVM", "run_frame", "REPLAY"]
__all__ = ["REPLAY", "PagedooVM", "run_frame"]
# ---------------------------------------------------------------- 辅助
@@ -10,7 +10,6 @@ import json
from pathlib import Path
from typing import Any
PAY_APPID = "1450243039"
PAY_GOODS_URL = "https://pay.qq.com/midas/minipay_v2/views/cpay/goods.shtml"
PAY_SAVE_URL = f"https://api.unipay.qq.com/v1/r/{PAY_APPID}/web_save"
+1 -1
View File
@@ -68,7 +68,7 @@ class SessionState:
}
@classmethod
def from_json(cls, d: dict) -> "SessionState":
def from_json(cls, d: dict) -> SessionState:
return cls(
xmidas_ops=list(d.get("xmidas_ops", [])),
key16=list(d.get("key16", [])),
@@ -31,10 +31,10 @@ from pyvm.algorithm import (
build_plaintext,
derive_key1_from_key16,
generate_encrypt_msg_offline,
) # noqa: E402
from pyvm.login_profile import midas_login_params # noqa: E402
from pyvm.payment_errors import describe_payment_failure # noqa: E402
from pyvm.protocol import ( # noqa: E402
)
from pyvm.login_profile import midas_login_params
from pyvm.payment_errors import describe_payment_failure
from pyvm.protocol import (
DEFAULT_ORDER_PF,
GOODS_USER_AGENT,
PAY_APPID,
@@ -450,7 +450,6 @@ def cmd_check_only(session_path: Path, out_dir: Path) -> int:
from pyvm.order_status import (
completion_summary,
get_official_orders,
is_finished,
)
session = load_json(session_path)
@@ -697,7 +696,7 @@ def main() -> int:
out_dir, fields, int(fp.get("device_fp_length", 0)), plaintext_length
)
body = urllib.parse.urlencode(fields)
from pyvm.order_status import order_completion_states, get_official_orders
from pyvm.order_status import get_official_orders, order_completion_states
# 尽量在发起支付前建立基线,缩小极快支付造成的检测窗口;失败不阻塞支付,付款码生成后重试。
baseline_document = None
@@ -17,8 +17,8 @@ from pathlib import Path
from urllib.error import HTTPError
from urllib.parse import urlencode
from urllib.request import (
HTTPRedirectHandler,
HTTPCookieProcessor,
HTTPRedirectHandler,
Request,
build_opener,
)
@@ -43,7 +43,7 @@ USER_AGENT = (
class NoRedirect(HTTPRedirectHandler):
"""Keep OAuth redirects visible while CookieJar receives Set-Cookie headers."""
def redirect_request(self, req, fp, code, msg, headers, newurl): # noqa: D401
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
@@ -118,7 +118,7 @@ def g_tk(p_skey: str) -> int:
def parse_poll(body: str) -> tuple[int, str]:
match = re.search(r"ptuiCB\((.*)\)", body, re.S)
match = re.search(r"ptuiCB\((.*)\)", body, re.DOTALL)
if not match:
raise ValueError("QQ 二维码轮询响应缺少 ptuiCB")
values = re.findall(r"'([^']*)'", match.group(1))
@@ -20,8 +20,8 @@ from pathlib import Path
from urllib.error import HTTPError
from urllib.parse import urlencode
from urllib.request import (
HTTPRedirectHandler,
HTTPCookieProcessor,
HTTPRedirectHandler,
Request,
build_opener,
)
@@ -42,7 +42,7 @@ USER_AGENT = (
class NoRedirect(HTTPRedirectHandler):
"""保留 OAuth 回调的 302 和 Set-Cookie。"""
def redirect_request(self, req, fp, code, msg, headers, newurl): # noqa: D401
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
@@ -88,7 +88,7 @@ def extract_uuid(page: str) -> str:
r"connect/qrcode/([A-Za-z0-9_-]{8,64})",
r"uuid=([A-Za-z0-9_-]{8,64})",
):
match = re.search(pattern, page, re.I)
match = re.search(pattern, page, re.IGNORECASE)
if match:
return match.group(1)
raise ValueError("微信授权页未找到二维码 UUID")
@@ -18,7 +18,7 @@ from curl_cffi import requests
ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT))
from pyvm.login_profile import midas_login_params # noqa: E402
from pyvm.login_profile import midas_login_params
YYB_APP_ID = 52575843
SOURCE_ID = "24292013"
@@ -32,7 +32,7 @@ WORKER_KEY = os.environ.get("YYB_WORKER_KEY", "")
_jobs: dict[str, dict] = {}
_lock = threading.Lock()
from pyvm.payment_errors import describe_payment_failure # noqa: E402
from pyvm.payment_errors import describe_payment_failure
def _payment_failure_message(job: dict, phase: str, fallback: str) -> str:
@@ -81,13 +81,13 @@ def _safe_log(job: dict, line: str) -> None:
clean = re.sub(r"HOLD_[A-Za-z0-9_-]+", "[订单已隐藏]", clean)
clean = re.sub(r"(订单\s*[:]\s*)\S+", r"\1[订单已隐藏]", clean)
clean = re.sub(
r"(?:token|openid|openkey|cookie)=\S+", "[敏感字段已隐藏]", clean, flags=re.I
r"(?:token|openid|openkey|cookie)=\S+", "[敏感字段已隐藏]", clean, flags=re.IGNORECASE
)
clean = re.sub(
r"(?:pay_token|web_token|anti_token|session_id|sessionid)\s*[:= ]\s*\S+",
"[敏感字段已隐藏]",
clean,
flags=re.I,
flags=re.IGNORECASE,
)
timestamp = time.strftime("%H:%M:%S")
with _lock:
@@ -523,7 +523,7 @@ class Handler(BaseHTTPRequestHandler):
value = self.headers.get("Authorization", "")
return value == f"Bearer {WORKER_KEY}"
def do_POST(self) -> None: # noqa: N802
def do_POST(self) -> None:
if not self._authorized():
return self._json(401, {"detail": "未授权"})
path = urlparse(self.path).path.strip("/").split("/")
@@ -687,7 +687,7 @@ class Handler(BaseHTTPRequestHandler):
except Exception as exc: # noqa: BLE001
return self._json(500, {"detail": str(exc)})
def do_GET(self) -> None: # noqa: N802
def do_GET(self) -> None:
if urlparse(self.path).path == "/health":
return self._json(200, {"status": "ok"})
if not self._authorized():
@@ -8,7 +8,6 @@ import unittest
from pathlib import Path
from urllib.parse import parse_qs
_SCRIPT = Path(__file__).resolve().parents[1] / "scripts" / "jsdom-pay.py"
_SPEC = importlib.util.spec_from_file_location("yyb_jsdom_pay", _SCRIPT)
assert _SPEC and _SPEC.loader
@@ -16,8 +15,8 @@ _MODULE = importlib.util.module_from_spec(_SPEC)
sys.modules[_SPEC.name] = _MODULE
_SPEC.loader.exec_module(_MODULE)
from pyvm.payment_errors import describe_payment_failure
from pyvm.algorithm import derive_key1_from_key16, generate_encrypt_msg_offline
from pyvm.payment_errors import describe_payment_failure
from pyvm.protocol import goods_material_diagnostics, validate_goods_materials