Android: new WebSocket() crashes the app for a URL that OkHttp or java.net.URI rejects

未關閉 適合新手
#59,704 1 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 2 天內回覆

@sorinc03 已經在處理了。

開始於 2026年11月2日。

  • #59757 來自 @sorinc03 —— 未關閉

評估

難度
2/5
預估耗時
1-3 小時
新手友好度
72/100
Issue 類型
缺陷
描述清晰度
基本清楚
活躍度
活躍
技術堆疊
android, java, react-native
領域
mobile

研究方向

閱讀 com.facebook.react.modules.websocket.WebSocketModule.java 並找到呼叫了 Request.Builder().url(url)、getCookie 和 getDefaultOrigin 的 connect 方法。將這些呼叫包裹在針對 IllegalArgumentException 的 try-catch 中,並像 send 和 close 那樣向 JS 分發一個 error/close 事件。Done 表示無效的 URL 會在 WebSocket 上觸發 error 和 close,而不是使應用程式崩潰。

由索引模型根據 Issue 內容生成。

描述

🌐Networking Needs: Author Feedback Needs: Repro Platform: Android
Description

On Android, new WebSocket(url) crashes the app when OkHttp or java.net.URI rejects url, such as ws://localhost:0/ (port 0) or ws://localhost:4000/a|b (a character RFC 2396 doesn't allow in a path). JavaScript gets no exception and no error or close event, and a release build dies with a fatal exception on the native modules thread.

Expected: the socket fires error and close, as it does when it can't connect, or the constructor throws in JavaScript.

Likely cause: WebSocketModule.connect calls Request.Builder().url(url), getCookie, and getDefaultOrigin outside a try, and they throw IllegalArgumentException for such URLs, while send and close catch their exceptions. #24427 reported the same crash in 0.59.

We found this in Evolu, a local-first platform, whose relay URL type now rejects such URLs.

Steps to reproduce
  1. Replace App.tsx of an app made from the reproducer template with the code below.
  2. Build it in release for Android and run it.
  3. Tap either button. The app crashes instead of showing error and close.
import { useState } from 'react';
import { Button, Text, View } from 'react-native';

// Each URL should report an error and close to JS. On Android, connect throws
// natively instead.
const urls = ['ws://localhost:0/', 'ws://localhost:4000/a|b'];

function App() {
  const [log, setLog] = useState<ReadonlyArray<string>>([]);
  const append = (line: string) => setLog(lines => [...lines, line]);

  return (
    <View style={{ padding: 48, gap: 16 }}>
      {urls.map(url => (
        <Button
          key={url}
          title={url}
          onPress={() => {
            const socket = new WebSocket(url);
            socket.onerror = () => append(`error ${url}`);
            socket.onclose = event => append(`close ${url} ${event.code}`);
          }}
        />
      ))}
      {log.map((line, index) => (
        <Text key={index}>{line}</Text>
      ))}
    </View>
  );
}

export default App;
React Native Version

0.88.1

Affected Platforms

Runtime - Android, Build - MacOS

Output of npx @react-native-community/cli info
System:
  OS: macOS 26.6.2
  CPU: (10) arm64 Apple M5
Binaries:
  Node: 24.22.0
npmPackages:
  react-native: 0.88.1
Android:
  hermesEnabled: true
  newArchEnabled: true
Device: Android 16 (API 36) arm64 emulator
Stacktrace or Logs
E AndroidRuntime: FATAL EXCEPTION: mqt_v_native
E AndroidRuntime: java.lang.IllegalArgumentException: Invalid URL port: "0"
E AndroidRuntime:   at t6.m(r8-map-id-50fb0331…:24)
E AndroidRuntime:   at vv.c(r8-map-id-50fb0331…:513)
E AndroidRuntime:   at xi.h(r8-map-id-50fb0331…:50)
E AndroidRuntime:   at com.facebook.react.modules.websocket.WebSocketModule.connect(r8-map-id-50fb0331…:118)
E AndroidRuntime:   at com.facebook.jni.NativeRunnable.run(Native Method)
E AndroidRuntime:   at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(…)

E AndroidRuntime: FATAL EXCEPTION: mqt_v_native
E AndroidRuntime: java.lang.IllegalArgumentException: Unable to set ws://localhost:4000/a|b as default origin header
E AndroidRuntime:   at com.facebook.react.modules.websocket.WebSocketModule.getCookie(r8-map-id-50fb0331…:8)
E AndroidRuntime:   at com.facebook.react.modules.websocket.WebSocketModule.connect(r8-map-id-50fb0331…:121)
MANDATORY Reproducer

No repository: the App.tsx in Steps to reproduce is the whole reproducer.

Screenshots and Videos

No response

主要語言
C++
星號
127k
分支
25.4k
平均合併
2 天 9 小時
30 天內合併 PR
91

環境準備

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

react/react-native 的其他 Issue

查看 react/react-native 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。