Skip to content

fix(realtime): encode broadcast header fields as UTF-8#2516

Merged
edgurgel merged 1 commit into
supabase:masterfrom
PedroHenrique0713:fix/realtime-serializer-utf8
Jul 13, 2026
Merged

fix(realtime): encode broadcast header fields as UTF-8#2516
edgurgel merged 1 commit into
supabase:masterfrom
PedroHenrique0713:fix/realtime-serializer-utf8

Conversation

@PedroHenrique0713

@PedroHenrique0713 PedroHenrique0713 commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

🔍 Description

What changed?

In the binary broadcast serializer, the header fields (join_ref, ref, topic, event, metadata) are now length-prefixed and written as UTF-8 bytes, instead of using String.length for the size prefix and charCodeAt(0) for the bytes.

Why was this change needed?

The decode side reads these fields with TextDecoder (UTF-8), but the encode side measured them with String.length (UTF-16 code units) and wrote them with char.charCodeAt(0) (one truncated byte per code unit). For any non-ASCII value — e.g. a broadcast event name like café or an emoji — this:

  • writes the wrong length prefix (café4 instead of 5 UTF-8 bytes),
  • corrupts multi-byte characters (café decodes back as caf�),
  • desynchronizes the whole buffer for characters outside the BMP (String.length counts 2 code units for 🎉, but Array.from(...) iterated 1 code point, so the declared size and the bytes written disagreed).

Using TextEncoder + Uint8Array.set() makes the encode side byte-accurate and consistent with the UTF-8 decode. ASCII values are unaffected (UTF-8 bytes equal the char codes and byte length equals string length), so the existing tests are unchanged.

🔄 Breaking changes

  • This PR contains no breaking changes

📋 Checklist

  • I have read the Contributing Guidelines
  • My PR title follows the conventional commit format
  • I have run pnpm nx format to ensure consistent code formatting
  • I have added tests for new functionality (if applicable)
  • I have updated documentation (if applicable)

📝 Additional notes

Added a binary test that encodes a non-ASCII event (café-🎉) and asserts the length prefix equals the UTF-8 byte length and that the written bytes round-trip through TextDecoder. The test fails on master (expected 7 to be 10) and passes with this change. Verified locally: vitest run test/serializer.test.ts → 24 passed, tsc --noEmit → clean, prettier --check → clean.

@PedroHenrique0713
PedroHenrique0713 requested review from a team as code owners July 12, 2026 01:51
@pkg-pr-new

pkg-pr-new Bot commented Jul 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

@supabase/auth-js

npm i https://pkg.pr.new/@supabase/auth-js@2516

@supabase/functions-js

npm i https://pkg.pr.new/@supabase/functions-js@2516

@supabase/postgrest-js

npm i https://pkg.pr.new/@supabase/postgrest-js@2516

@supabase/realtime-js

npm i https://pkg.pr.new/@supabase/realtime-js@2516

@supabase/storage-js

npm i https://pkg.pr.new/@supabase/storage-js@2516

@supabase/supabase-js

npm i https://pkg.pr.new/@supabase/supabase-js@2516

commit: 8d489cb

@coveralls

coveralls commented Jul 12, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 80.461% (+0.02%) from 80.446% — PedroHenrique0713:fix/realtime-serializer-utf8 into supabase:master

@PedroHenrique0713

Copy link
Copy Markdown
Contributor Author

Thanks for the re-run, @edgurgel. This one looks like the integration job hitting a Docker Hub pull rate limit (toomanyrequests: Rate exceeded) while pulling the service images, rather than a test regression — the realtime broadcast tests passed in both attempts. Happy to rebase or push whenever it's useful to trigger CI again.

@edgurgel edgurgel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks!

@edgurgel
edgurgel merged commit b4ddbd5 into supabase:master Jul 13, 2026
29 of 30 checks passed
mandarini pushed a commit to supabase/ssr that referenced this pull request Jul 14, 2026
This PR updates `@supabase/supabase-js` to v2.110.5.

**Source**: supabase-js-stable-release

---

## Release Notes

## v2.110.5

## 2.110.5 (2026-07-14)

### 🩹 Fixes

- **supabase:** avoid edge runtime warning
([#2522](supabase/supabase-js#2522))

### ❤️ Thank You

- Vaibhav @7ttp
## v2.110.4

## 2.110.4 (2026-07-14)

### 🩹 Fixes

- **functions:** stop sending API key in Authorization header for
function calls
([#2511](supabase/supabase-js#2511))
- **realtime:** encode broadcast header fields as UTF-8
([#2516](supabase/supabase-js#2516))

### ❤️ Thank You

- Katerina Skroumpelou @mandarini
- Pedro Henrique

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
mandarini pushed a commit to supabase/supabase that referenced this pull request Jul 14, 2026
This PR updates @supabase/*-js libraries to version 2.110.5.

**Source**: supabase-js-stable-release

**Changes**:
- Updated @supabase/supabase-js to 2.110.5
- Updated @supabase/auth-js to 2.110.5
- Updated @supabase/realtime-js to 2.110.5
- Updated @supabase/postgest-js to 2.110.5
- Refreshed pnpm-lock.yaml

---

## Release Notes

## v2.110.5

## 2.110.5 (2026-07-14)

### 🩹 Fixes

- **supabase:** avoid edge runtime warning
([#2522](supabase/supabase-js#2522))

### ❤️ Thank You

- Vaibhav @7ttp
## v2.110.4

## 2.110.4 (2026-07-14)

### 🩹 Fixes

- **functions:** stop sending API key in Authorization header for
function calls
([#2511](supabase/supabase-js#2511))
- **realtime:** encode broadcast header fields as UTF-8
([#2516](supabase/supabase-js#2516))

### ❤️ Thank You

- Katerina Skroumpelou @mandarini
- Pedro Henrique
## v2.110.3

## 2.110.3 (2026-07-13)

### 🩹 Fixes

- **auth:** preserve pkce verifier
([#2513](supabase/supabase-js#2513))
- **postgrest:** pin tstyche target off floating latest
([#2509](supabase/supabase-js#2509))

### ❤️ Thank You

- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp
## v2.110.2

## 2.110.2 (2026-07-09)

### 🩹 Fixes

- **auth:** clear local session on signout failures
([#2504](supabase/supabase-js#2504))

### ❤️ Thank You

- Luc Peng

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
mandarini pushed a commit to supabase/supabase that referenced this pull request Jul 15, 2026
This PR updates @supabase/*-js libraries to version 2.110.6.

**Source**: supabase-js-stable-release

**Changes**:
- Updated @supabase/supabase-js to 2.110.6
- Updated @supabase/auth-js to 2.110.6
- Updated @supabase/realtime-js to 2.110.6
- Updated @supabase/postgest-js to 2.110.6
- Refreshed pnpm-lock.yaml

---

## Release Notes

## v2.110.6

## 2.110.6 (2026-07-15)

### 🩹 Fixes

- **postgrest:** type hinted self-referencing embeds as arrays
([#2520](supabase/supabase-js#2520))
- **realtime:** forward opts to send() in track()
([#2490](supabase/supabase-js#2490))
- **supabase:** warn instead of throw for unrecognized sb_ API key
subtypes ([#2526](supabase/supabase-js#2526))

### ❤️ Thank You

- Franco Kaddour @FrancoKaddour
- Katerina Skroumpelou @mandarini
## v2.110.5

## 2.110.5 (2026-07-14)

### 🩹 Fixes

- **supabase:** avoid edge runtime warning
([#2522](supabase/supabase-js#2522))

### ❤️ Thank You

- Vaibhav @7ttp
## v2.110.4

## 2.110.4 (2026-07-14)

### 🩹 Fixes

- **functions:** stop sending API key in Authorization header for
function calls
([#2511](supabase/supabase-js#2511))
- **realtime:** encode broadcast header fields as UTF-8
([#2516](supabase/supabase-js#2516))

### ❤️ Thank You

- Katerina Skroumpelou @mandarini
- Pedro Henrique
## v2.110.3

## 2.110.3 (2026-07-13)

### 🩹 Fixes

- **auth:** preserve pkce verifier
([#2513](supabase/supabase-js#2513))
- **postgrest:** pin tstyche target off floating latest
([#2509](supabase/supabase-js#2509))

### ❤️ Thank You

- Katerina Skroumpelou @mandarini
- Vaibhav @7ttp
## v2.110.2

## 2.110.2 (2026-07-09)

### 🩹 Fixes

- **auth:** clear local session on signout failures
([#2504](supabase/supabase-js#2504))

### ❤️ Thank You

- Luc Peng

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.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.

3 participants