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

Ouverte Adaptée aux débutants
#59,704 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 2 jours

@sorinc03 y travaille déjà.

Depuis le 2/11/2026.

  • #59757 par @sorinc03 — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
72/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
android, java, react-native
Domaine
mobile

Piste de recherche

Lis com.facebook.react.modules.websocket.WebSocketModule.java et localise la méthode connect où Request.Builder().url(url), getCookie et getDefaultOrigin sont appelés. Encapsule ces appels dans un try-catch pour IllegalArgumentException et envoie un événement error/close au JS comme le font send et close. Done signifie que les URLs invalides déclenchent error et close sur le WebSocket au lieu de planter l'app.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

🌐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

Langage dominant
C++
Étoiles
127k
Forks
25.4k
Merge moyen
2 j 9 h
PR mergées (30 j)
91

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de react/react-native

Toutes les issues de react/react-native

Issues similaires

Plus d'issues C++

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.