feat: 服务端集成自动打包流程
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
|
||||
def build_canonical_symbol_tables(
|
||||
swift_files: list,
|
||||
objc_files: list,
|
||||
method_files: list,
|
||||
*,
|
||||
enable_objc_symbols: bool,
|
||||
prefilter_files,
|
||||
type_pattern: str,
|
||||
method_pattern: str,
|
||||
extract_swift_symbols,
|
||||
extract_objc_symbols,
|
||||
extract_methods,
|
||||
objc_symbol_prefixes: tuple,
|
||||
already_obfuscated_re,
|
||||
symbol_whitelist,
|
||||
symbol_prefix_whitelist: tuple,
|
||||
is_system_method,
|
||||
split_swift_signature_key,
|
||||
) -> dict:
|
||||
swift_symbol_files = prefilter_files(swift_files, type_pattern)
|
||||
objc_symbol_files = prefilter_files(objc_files, type_pattern) if enable_objc_symbols else []
|
||||
method_symbol_files = prefilter_files(method_files, method_pattern)
|
||||
|
||||
swift_symbols = set()
|
||||
objc_symbols = set()
|
||||
direct_methods = set()
|
||||
objc_selectors = set()
|
||||
swift_signatures = {}
|
||||
|
||||
for file_path in swift_symbol_files:
|
||||
swift_symbols.update(extract_swift_symbols(file_path))
|
||||
|
||||
for file_path in objc_symbol_files:
|
||||
objc_symbols.update(extract_objc_symbols(file_path))
|
||||
|
||||
for file_path in method_symbol_files:
|
||||
method_data = extract_methods(file_path)
|
||||
direct_methods.update(method_data["direct_names"])
|
||||
objc_selectors.update(method_data["objc_selectors"])
|
||||
swift_signatures.update(method_data["swift_signatures"])
|
||||
|
||||
canonical = {
|
||||
"swift_symbols": sorted(swift_symbols),
|
||||
"objc_symbols": [
|
||||
name for name in sorted(objc_symbols)
|
||||
if any(name.startswith(prefix) for prefix in objc_symbol_prefixes)
|
||||
and not already_obfuscated_re.match(name)
|
||||
and name not in symbol_whitelist
|
||||
and not name.startswith(symbol_prefix_whitelist)
|
||||
],
|
||||
"direct_methods": [
|
||||
name for name in sorted(direct_methods)
|
||||
if name and not already_obfuscated_re.match(name) and name not in symbol_whitelist and not is_system_method(name)
|
||||
],
|
||||
"objc_selectors": [
|
||||
name for name in sorted(objc_selectors)
|
||||
if name and not already_obfuscated_re.match(name) and name not in symbol_whitelist and not is_system_method(name)
|
||||
],
|
||||
"swift_signatures": {},
|
||||
}
|
||||
|
||||
for signature_key in sorted(swift_signatures.keys()):
|
||||
base_name, _ = split_swift_signature_key(signature_key)
|
||||
if not base_name:
|
||||
continue
|
||||
if already_obfuscated_re.match(base_name) or base_name in symbol_whitelist or is_system_method(base_name):
|
||||
continue
|
||||
canonical["swift_signatures"][signature_key] = swift_signatures[signature_key]
|
||||
|
||||
digest_payload = {
|
||||
key: canonical[key]
|
||||
for key in ("swift_symbols", "objc_symbols", "direct_methods", "objc_selectors", "swift_signatures")
|
||||
}
|
||||
canonical["digest"] = hashlib.sha256(
|
||||
json.dumps(digest_payload, ensure_ascii=False, sort_keys=True).encode("utf-8")
|
||||
).hexdigest()
|
||||
return canonical
|
||||
|
||||
|
||||
def build_type_mappings_from_canonical_table(canonical_tables: dict, salt: str, *, enable_objc_symbols: bool, build_unique_mapping, type_prefix: str) -> tuple:
|
||||
ordered_names = []
|
||||
seen = set()
|
||||
for bucket_name in ("objc_symbols", "swift_symbols"):
|
||||
for name in canonical_tables.get(bucket_name, []):
|
||||
if name in seen:
|
||||
continue
|
||||
seen.add(name)
|
||||
ordered_names.append(name)
|
||||
|
||||
combined_mapping = build_unique_mapping(ordered_names, salt, prefix=type_prefix)
|
||||
mapping_swift = {
|
||||
name: combined_mapping[name]
|
||||
for name in canonical_tables.get("swift_symbols", [])
|
||||
if name in combined_mapping
|
||||
}
|
||||
mapping_objc = {}
|
||||
if enable_objc_symbols:
|
||||
mapping_objc = {
|
||||
name: combined_mapping[name]
|
||||
for name in canonical_tables.get("objc_symbols", [])
|
||||
if name in combined_mapping
|
||||
}
|
||||
return mapping_swift, mapping_objc
|
||||
|
||||
|
||||
def build_method_mapping_from_canonical_table(canonical_tables: dict, salt: str, *, build_unique_mapping, method_prefix: str) -> dict:
|
||||
swift_signature_mapping = canonical_tables.get("swift_signatures", {})
|
||||
ordered_names = []
|
||||
seen = set()
|
||||
for bucket in (
|
||||
canonical_tables.get("direct_methods", []),
|
||||
canonical_tables.get("objc_selectors", []),
|
||||
sorted(swift_signature_mapping.keys()),
|
||||
):
|
||||
for name in bucket:
|
||||
if name in seen:
|
||||
continue
|
||||
seen.add(name)
|
||||
ordered_names.append(name)
|
||||
|
||||
combined_tokens = build_unique_mapping(ordered_names, salt, prefix=method_prefix)
|
||||
method_mapping = {
|
||||
name: combined_tokens[name]
|
||||
for name in canonical_tables.get("direct_methods", [])
|
||||
if name in combined_tokens
|
||||
}
|
||||
method_mapping.update({
|
||||
name: combined_tokens[name]
|
||||
for name in canonical_tables.get("objc_selectors", [])
|
||||
if name in combined_tokens
|
||||
})
|
||||
|
||||
for signature_key in sorted(swift_signature_mapping.keys()):
|
||||
if signature_key not in combined_tokens:
|
||||
continue
|
||||
entry = dict(swift_signature_mapping[signature_key])
|
||||
entry["obfuscated"] = combined_tokens[signature_key]
|
||||
method_mapping[signature_key] = entry
|
||||
|
||||
return method_mapping
|
||||
Reference in New Issue
Block a user