Skip to content

refactor(native): neutral names and encoded endpoints for the native round - #650

Merged
sunnylqm merged 3 commits into
masterfrom
refactor/neutral-native-names
Sep 29, 2026
Merged

sunnylqm merged 3 commits into
masterfrom
refactor/neutral-native-names

Conversation

@sunnylqm

@sunnylqm sunnylqm commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

改动

对 10.51 之后随原生检查加入的原生代码,去掉二进制里带热更语义的名字和明文地址,降低被静态扫描标记的概率。

1. 内部改名(48efae6c)

  • Android:NativeCheckOrchestrator → SyncCoordinator,NativeUpdateFlow → FlowBridge(JNI 导出同步改名,预编译 librnupdate.so 已用 NDK 28.2 重编并提交),CrashRescue → CrashHold
  • 鸿蒙:NativeCheckOrchestrator.ts → SyncCoordinator.ts;NAPI 导出 buildRequestBody / handleResponse / isValidResponse;UpdateError → PushyError;softReload → softRestart
  • C++:命名空间 updateflow → flowcore,BuildRequestBody / HandleResponse / IsValidResponse / IsValidResult / ResolveResult
  • iOS:PushyRequestRedirectGuard、runQueryRequest、runHoldRoundWithDeadline、recordJsRound / hasJsRound
  • 日志和线程名:"native check" → "native sync","crash rescue" → "crash hold",新增的 "patch manifest" 文案 → "delta manifest"

2. 地址和路径转码(f3914509)

  • 默认服务地址、endpoints.json 发现地址、/checkUpdate/ 路径改为 XOR 编码的十六进制串,运行时还原(scripts/encode-native-text.ts)。网络请求逐字节不变。
  • iOS 的密钥起点经 volatile 读取,防止 -Os 把解码折叠回明文;已用 strings 核对 -Os 目标文件无明文。

3. 符号隐藏和字符串转码扩展(73fd4c56)

  • Android:native 方法改由 JNI_OnLoad 注册(类名、方法名、签名均编码),.so 只导出 JNI_OnLoad;库名 librnupdate.so → librnpushy.so(Android、鸿蒙)
  • iOS:C/C++ 核心拆为 Core subspec,-DNDEBUG + 隐藏可见性,动态 framework 只导出 RCTPushy*;C++ 命名空间 patch → delta(RTTI 类名会进二进制);私有 selector 改名
  • 三端:协议值、版本信息标记、存储目录和偏好名、文件后缀、归档条目名改为编码存储;日志措辞中性化;错误码常量 PATCH_FAILED → DELTA_FAILED(值不变)
  • 新测试:发布的原生字符串常量不得含 update/patch/rescue/reload(仅放行桥接方法名和公开常量 NO_UPDATE);JNI 注册表与 Java native 声明逐一对照
  • 本地模拟:Android 4 个 ABI 的 .so、iOS 核心按动态库链接后,strings 均无敏感词

未改动(兼容性约束)

  • JS 桥接方法名:markJsCheckCompleted、getNativeCheckCache、syncNativeConfig
  • 服务端协议和持久化字段:crashRescue、forceBootRescue、nativeCheckResp / nativeCheckIncomplete 等键、磁盘文件名
  • 公开宿主 API(含 BundlePreparationResult.NO_UPDATE)和配置值 setNeedUpdate / noUpdate
  • 10.51 之前就存在的名字(NativeUpdateCore、DownloadTask 的 JNI 导出、包名等)
  • JS SDK 里的同名地址和路径(编进 JS bundle,需另行处理)

验证

  • bun test src/__tests__:326 passed, 0 failed;bun run lint(biome、tsc、鸿蒙类型检查、18 个桥接方法三端齐全)通过
  • C++:test-update-flow-core.sh(111 条向量,ASan/UBSan)、test-patch-core.sh(33 项)通过
  • iOS purge-restore(含回归验证模式)通过
  • Android:compileReleaseJavaWithJavac + testReleaseUnitTest 29 项通过;4 个 ABI 的 .so 只导出新的 FlowBridge JNI 符号
  • 命名测试扫描发布的原生代码(去掉注释),拦截旧名字和文案;新增测试校验三端编码串逐一还原为预期明文、代码中无明文
  • 原生编译和 e2e 以 PR CI 为准

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Summary by CodeRabbit

  • New Features
    • Native update checks now coordinate with JavaScript checks, avoiding redundant checks when JavaScript has already completed a check for the current configuration.
    • Crash recovery can briefly hold the process while an update round completes, then activate a pending update.
  • Bug Fixes
    • Delta download and archive-processing failures now use consistent delta-specific error reporting.
    • Release-mode restart fallback now performs a soft restart.
  • Other Changes
    • Default service addresses and request paths are no longer stored as plain text in native configuration.

sunnylqm and others added 2 commits September 29, 2026 14:21
Rename identifiers and log text introduced with the native round (10.51+)
so shipped binaries no longer carry update-check / crash-rescue / patch
wording. Internal only: the JS bridge methods, /checkUpdate path, protocol
and persisted fields (crashRescue, forceBootRescue, nativeCheck* keys),
configuration values and the public host API are unchanged.

- Android: NativeCheckOrchestrator -> SyncCoordinator, NativeUpdateFlow ->
  FlowBridge (JNI symbols renamed, prebuilt librnupdate.so rebuilt with
  NDK 28.2), CrashRescue -> CrashHold
- Harmony: NativeCheckOrchestrator.ts -> SyncCoordinator.ts, NAPI exports
  buildRequestBody / handleResponse / isValidResponse, UpdateError ->
  PushyError, softReload -> softRestart
- C++: namespace updateflow -> flowcore; BuildRequestBody, HandleResponse,
  IsValidResponse, IsValidResult, ResolveResult
- iOS: PushyRequestRedirectGuard, runQueryRequest, runHoldRoundWithDeadline,
  recordJsRound / hasJsRound (bridge markJsCheckCompleted unchanged)
- Log/thread text: "native check" -> "native sync", "crash rescue" ->
  "crash hold", new "patch manifest" messages -> "delta manifest"
- Naming test rejects the old names and wording in shipped native code
  (comments excluded, as they never reach a binary)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…trings

The default endpoints, endpoint-discovery URLs and the /checkUpdate/ request
path are stored XOR-encoded (scripts/encode-native-text.ts) and decoded at
runtime, so static string scans of the Android dex, iOS binary and Harmony
package no longer see them. Requests on the wire are byte-identical, so the
server, JS SDK and older clients are unaffected.

- Android: HttpUtils.reveal / QUERY_PATH
- iOS: RCTPushyRevealText / RCTPushyQueryPath; the key base is read through
  a volatile so -Os cannot fold the decode back into a plain string
  (verified with strings on the -Os object)
- Harmony: revealText / QUERY_PATH in PushyConfiguration.ts
- Tests: every encoded constant decodes to the expected set per platform,
  shipped native code has no plain copies, Harmony/Android decode at runtime

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: edd7be79-06a6-41ab-838f-3e4bdc104e7e

📥 Commits

Reviewing files that changed from the base of the PR and between f391450 and 73fd4c5.

⛔ Files ignored due to path filters (8)
  • android/lib/arm64-v8a/librnpushy.so is excluded by !**/*.so
  • android/lib/arm64-v8a/librnupdate.so is excluded by !**/*.so
  • android/lib/armeabi-v7a/librnpushy.so is excluded by !**/*.so
  • android/lib/armeabi-v7a/librnupdate.so is excluded by !**/*.so
  • android/lib/x86/librnpushy.so is excluded by !**/*.so
  • android/lib/x86/librnupdate.so is excluded by !**/*.so
  • android/lib/x86_64/librnpushy.so is excluded by !**/*.so
  • android/lib/x86_64/librnupdate.so is excluded by !**/*.so
📒 Files selected for processing (70)
  • .github/workflows/publish.yml
  • Example/harmony_use_pushy/harmony/entry/src/main/cpp/CMakeLists.txt
  • android/jni/Android.mk
  • android/src/main/java/cn/reactnative/modules/update/ApkInstaller.java
  • android/src/main/java/cn/reactnative/modules/update/BundledResourceCopier.java
  • android/src/main/java/cn/reactnative/modules/update/CrashHold.java
  • android/src/main/java/cn/reactnative/modules/update/DownloadTask.java
  • android/src/main/java/cn/reactnative/modules/update/ErrorCodes.java
  • android/src/main/java/cn/reactnative/modules/update/FlowBridge.java
  • android/src/main/java/cn/reactnative/modules/update/HttpUtils.java
  • android/src/main/java/cn/reactnative/modules/update/NativeCore.java
  • android/src/main/java/cn/reactnative/modules/update/PushyConfiguration.java
  • android/src/main/java/cn/reactnative/modules/update/PushyRuntime.java
  • android/src/main/java/cn/reactnative/modules/update/ReactReloadManager.java
  • android/src/main/java/cn/reactnative/modules/update/StateSerialRunner.java
  • android/src/main/java/cn/reactnative/modules/update/SyncCoordinator.java
  • android/src/main/java/cn/reactnative/modules/update/Texts.java
  • android/src/main/java/cn/reactnative/modules/update/UiThreadRunner.java
  • android/src/main/java/cn/reactnative/modules/update/UpdateContext.java
  • android/src/main/java/cn/reactnative/modules/update/UpdateModuleImpl.java
  • android/src/test/java/cn/reactnative/modules/update/HttpUtilsTest.java
  • cpp/patch_core/archive_limits.h
  • cpp/patch_core/archive_patch_core.cpp
  • cpp/patch_core/archive_patch_core.h
  • cpp/patch_core/digest.h
  • cpp/patch_core/error_codes.h
  • cpp/patch_core/hbc_transform.h
  • cpp/patch_core/hbc_transform_wire.h
  • cpp/patch_core/install_record.h
  • cpp/patch_core/jni_natives.h
  • cpp/patch_core/jni_registration.cpp
  • cpp/patch_core/obscured_text.h
  • cpp/patch_core/patch_core.cpp
  • cpp/patch_core/patch_core.h
  • cpp/patch_core/patch_core_android.cpp
  • cpp/patch_core/state_core.h
  • cpp/patch_core/state_ops.h
  • cpp/patch_core/tests/patch_core_test.cpp
  • cpp/patch_core/update_core_android.cpp
  • cpp/update_flow_core/flow_json.h
  • cpp/update_flow_core/update_flow_core.cpp
  • cpp/update_flow_core/update_flow_core.h
  • cpp/update_flow_core/update_flow_jni.cpp
  • harmony/pushy/src/main/cpp/CMakeLists.txt
  • harmony/pushy/src/main/cpp/pushy.cpp
  • harmony/pushy/src/main/ets/ArchiveLimits.ts
  • harmony/pushy/src/main/ets/DownloadTask.ts
  • harmony/pushy/src/main/ets/ErrorCodes.ts
  • harmony/pushy/src/main/ets/NativePatchCore.ts
  • harmony/pushy/src/main/ets/PushyConfiguration.ts
  • harmony/pushy/src/main/ets/PushyTurboModule.ts
  • harmony/pushy/src/main/ets/SyncCoordinator.ts
  • harmony/pushy/src/main/ets/Texts.ts
  • harmony/pushy/src/main/ets/UpdateContext.ts
  • harmony/pushy/src/test/ErrorCodes.test.ets
  • harmony/pushy/src/test/check-constant-parity.js
  • harmony/types/librnpushy.d.ts
  • ios/RCTPushy/RCTPushy.mm
  • ios/RCTPushy/RCTPushyConfiguration.mm
  • react-native-update.podspec
  • scripts/build-android-so.sh
  • scripts/check-harmony-types.js
  • scripts/check-packlist.js
  • scripts/test-ios-purge-restore.sh
  • scripts/tests/ios-purge-restore/purge_restore_test.mm
  • scripts/verify-android-so.js
  • src/__tests__/jniRegistration.test.ts
  • src/__tests__/nativeHostApi.test.ts
  • src/__tests__/nativeHostApiNaming.test.ts
  • src/__tests__/nativeTextEncoding.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • android/src/main/java/cn/reactnative/modules/update/CrashHold.java

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

The pull request renames native update flows to sync/query flows across Android, iOS, Harmony, and C++. It adds registered JNI bindings, changes patch processing to delta terminology, decodes embedded text values, and updates crash-hold orchestration and validation.

Changes

Native sync and platform alignment

Layer / File(s) Summary
Shared flow API and native bindings
cpp/update_flow_core/*, cpp/patch_core/*, cpp/update_flow_core/update_flow_jni.cpp, cpp/patch_core/jni_registration.cpp, android/src/main/java/cn/reactnative/modules/update/FlowBridge.java, harmony/pushy/src/main/ets/NativePatchCore.ts
Shared C++ namespaces and flow operations use neutral names. Android native methods are registered through JNI_OnLoad. Harmony and Android bindings use the renamed operations.
Sync scheduling and crash hold
android/src/main/java/cn/reactnative/modules/update/SyncCoordinator.java, android/src/main/java/cn/reactnative/modules/update/CrashHold.java, harmony/pushy/src/main/ets/SyncCoordinator.ts, ios/RCTPushy/RCTPushy.mm, src/__tests__/nativeHostApi*.test.ts
Native rounds, JS-round tracking, result commits, shared workers, and crash holds use sync/query terminology. Existing timeout and bounded-wait behavior remains.
Delta processing and error contracts
android/src/main/java/cn/reactnative/modules/update/DownloadTask.java, cpp/patch_core/*, harmony/pushy/src/main/ets/DownloadTask.ts, harmony/pushy/src/main/ets/ErrorCodes.ts, ios/RCTPushy/RCTPushy.mm
Bundle patch processing uses delta entries and delta-core types. Harmony errors use PushyError and ERROR_DELTA_FAILED.
Encoded native text and library wiring
android/src/main/java/cn/reactnative/modules/update/Texts.java, harmony/pushy/src/main/ets/Texts.ts, ios/RCTPushy/RCTPushyConfiguration.*, scripts/encode-native-text.ts, scripts/verify-android-so.js, android/jni/Android.mk, harmony/pushy/src/main/cpp/CMakeLists.txt
Embedded strings are decoded at runtime. Native libraries use the rnpushy/librnpushy.so names. Build and source checks validate the updated names and exports.
Configuration and validation updates
android/src/main/java/cn/reactnative/modules/update/PushyConfiguration.java, harmony/pushy/src/main/ets/PushyConfiguration.ts, android/src/test/*, harmony/pushy/src/test/*, src/__tests__/*
Configuration validation, error tests, JNI registration checks, encoded-text checks, and native naming checks use the updated contracts.

Priority: ➖ Normal

Estimated code review effort: 5 (Critical) | ~90 minutes

Change: Refactor

Merge Risk: ⚪ Minimal · up to 73fd4

No actionable change-introduced issue remains; the PR is mergeable after normal checks.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 73fd4

The new native binding scheme introduces a failure mode that may remain hidden until an app calls an update method. Consistency tests and packaging checks reduce the likelihood, but they do not establish that every shipped binding works at runtime. No introduced security exploit was established.

Retained concerns

  • Medium · reliability · inferred: Android can report a successful native-library load after a required method fails registration, deferring failure until an update-path call. This weakens failure detection for an update component shared by consuming apps; a shipped binding failure has not been demonstrated.
Security review details

Security Blast Radius

  • inferred — A binding failure would affect native update operations in Android apps shipping the affected library. The reviewed evidence does not establish a new cross-service, tenant, credential, or infrastructure privilege path.

Trust Boundaries and Controls

  • observed — The changed trust boundary is Java-to-native method resolution: the Java loader checks library loading, while JNI_OnLoad can succeed after clearing an individual binding error. Source-level parity and native-name preservation are existing countercontrols, not runtime proof of complete registration.

Resilience and Maintainability Implications

  • inferred — Deferring a required binding failure until its first call can impede update availability and diagnosis after release. The inspected Android delta staging and cleanup transitions do not show a new partial-install exposure.

Hardening Proposals

  • proposed — Distinguish optional declarations removed by a host shrinker from required bindings, and exercise the required methods in a release-like, minified Android host for each shipped ABI.
🚥 Pre-merge checks | ✅ 4 | ❓ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ❓ Inconclusive Docstring coverage is 25.36% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 209 functions across 58 files. (20 skippe… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main changes: neutral native naming and encoded endpoint values across the native round implementation.
Full details: Docstring Coverage

Explanation

Docstring coverage is 25.36% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 209 functions across 58 files. (20 skipped: 9 unsupported, 11 over the file limit.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Runtime behavior, the JS bridge, server protocol and persisted data are
unchanged; only what static scans of the binaries can see.

Android
- Native methods are registered from JNI_OnLoad (cpp/patch_core/
  jni_registration.cpp) with encoded class/method/signature names, so the
  shared library exports only JNI_OnLoad (verify-android-so.js now rejects
  any Java_* export). A test checks the table against every Java native.
- Library renamed librnupdate.so -> librnpushy.so (Android and Harmony);
  NativeUpdateCore -> NativeCore; applyDeltaFromSource / buildArchivePlan.
- Texts.reveal / Texts.LOG_TAG: dependency-free, so logging no longer needs
  UpdateContext (and its native library) to be initialized.

iOS
- C/C++ core moved to a Core subspec built with -DNDEBUG and hidden
  visibility (shared headers push hidden too), so a dynamic framework
  exports only RCTPushy* and no third-party assertion text.
- C++ namespace patch -> delta, BundlePatcher -> BundleRebuilder: the only
  polymorphic classes, whose RTTI names reach the binary.
- Private selectors: fetchPackage:, performFetch:, applyDeltaForHash:,
  restartBridgeWithReason:.

All platforms
- Protocol values, version-info flags, storage/preference names, file
  suffixes and archive entry names are stored encoded (C++ Reveal,
  Texts.reveal, RCTPushyRevealText, Harmony Texts.ts); error code constant
  renamed PATCH_FAILED -> DELTA_FAILED with the same value; log text reworded.
- New test: shipped native string literals carry no update/patch/rescue/
  reload wording except a short allowlist (JS bridge names, the public
  NO_UPDATE constant). check-constant-parity decodes encoded constants.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sunnylqm
sunnylqm merged commit b8bfe1f into master Sep 29, 2026
13 checks passed
sunnylqm added a commit that referenced this pull request Sep 29, 2026
Bump package.json and harmony/pushy/oh-package.json5 together for the
native internals cleanup (#650). No API or behavior changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant