---
id: "CVE-2026-107218"
page: "https://infrastack.ai/live/CVE-2026-107218"
kind: "vulnerability"
aliases: ["CVE-2026-107218", "GHSA-8jjq-8j9w-m2v6", "GO-2026-6675"]
title: "Excelize: RIGHT() on supplementary-plane text slices with a negative index and panics"
severity: "medium"
cvss: 5.3
epss: 0.00309
exploited: false
status: "open"
category: "package"
products: [{"name": "github.com/xuri/excelize/v2", "fixed": ["2.11.1-0.20260908032718-ecd99d761fe0"], "affected": ">= 2.10.1, < 2.11.1-0.20260908032718-ecd99d761fe0", "ecosystem": "go"}, {"name": "excelize", "fixed": [], "affected": ">= 2.10.1, <= 2.11.0", "ecosystem": "vendor"}]
ecosystems: ["go", "vendor"]
tags: ["cwe-129", "excelize", "go", "package", "spreadsheets"]
not_affected_if: ["fixed-version", "no-formula-evaluation"]
published_at: "2026-10-07T19:17:34+00:00"
first_seen_at: "2026-11-06T00:09:02+00:00"
updated_at: "2026-11-06T00:19:08+00:00"
sources: [{"source": "govuln", "url": "https://pkg.go.dev/vuln/GO-2026-6675", "first_seen_at": "2026-11-06T00:09:02+00:00"}, {"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-107218", "first_seen_at": "2026-11-06T00:19:01+00:00"}, {"source": "ghsa", "url": "https://github.com/advisories/GHSA-8jjq-8j9w-m2v6", "first_seen_at": "2026-11-06T00:19:08+00:00"}]
exploit_sources: [{"type": "epss", "score": 0.00309, "url": "https://api.first.org/data/v1/epss?cve=CVE-2026-107218"}]
---

# Excelize: RIGHT() on supplementary-plane text slices with a negative index and panics

Link for people: https://infrastack.ai/live/CVE-2026-107218 (this .md is for agents)

The Go spreadsheet library Excelize panics when its RIGHT() formula function handles text containing supplementary-plane characters with a negative index. The sources do not say that an attacker can run code or read data; the impact described is a crash.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- go:github.com/xuri/excelize/v2 affected >= 2.10.1, < 2.11.1-0.20260908032718-ecd99d761fe0 fixed 2.11.1-0.20260908032718-ecd99d761fe0
- vendor:excelize affected >= 2.10.1, <= 2.11.0 fixed no fixed version listed

## How to check

- Check the version of `github.com/xuri/excelize/v2` in `go.mod` or with `go list -m github.com/xuri/excelize/v2`
- Check whether the application evaluates spreadsheet formulas on untrusted input
- Run `govulncheck ./...` to see whether the vulnerable function is reachable

## Fix

- `github.com/xuri/excelize/v2` to `2.11.1-0.20260908032718-ecd99d761fe0` or later

## Timeline

- 2026-11-06T00:09:02+00:00 govuln https://pkg.go.dev/vuln/GO-2026-6675
- 2026-11-06T00:19:01+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-107218
- 2026-11-06T00:19:08+00:00 ghsa https://github.com/advisories/GHSA-8jjq-8j9w-m2v6

## Documents

- [advisory] Vendor advisory: github.com https://github.com/qax-os/excelize/security/advisories/GHSA-8jjq-8j9w-m2v6
- [advisory] Maintainer's advisory: api.github.com https://api.github.com/repos/qax-os/excelize/security-advisories/GHSA-8jjq-8j9w-m2v6
- [fix] Patch: github.com https://github.com/qax-os/excelize/commit/ecd99d761fe0489f1ed308e2f7dc2e0502d1a396
- [fix] Patch: github.com https://github.com/qax-os/excelize/pull/2390

## From the sources

`leftRight` (calc.go:14236) tests the length with `countUTF16String`, which counts a rune above U+FFFF as 2. The RIGHT branch on 14241 then slices `[]rune(text)` at `utf8.RuneCountInString(text)-numChars`, which counts it as 1. For text with N such runes the two measures are 2N and N, so any `numChars` between them passes the guard and gives a negative index. The `numChars < 0` check at 14216 does not help, since the value that gets through is positive.

What makes it worth reporting is `AutoFitColWidth`, which evaluates formulas without looking like it does, so normalising an uploaded sheet is enough to reach it. One scoping correction to my own wording there: `AutoFitColWidth` was added in v2.11.0 and does not exist at v2.10.1, so on v2.10.1 the only reachable path is an explicit `CalcCellValue`.

A 6,077-byte file containing two U+1D7D9 characters in A1 and  RIGHT(A1,3)  in B1 was created and then opened in a separate program without recovery enabled:

```
v2.9.1    ok
v2.10.0   ok
v2.10.1   panic: slice bounds out of range [-1:]
v2.11.0   panic: slice bounds out of range [-1:]
```

So it is a regression, not an old defect. Commit a880146 (2026-01-16) moved the guard to `countUTF16String` and left the slice on the rune index, and `git tag --contains` gives v2.10.1 and v2.11.0 only.

RIGHT only. RIGHTB reaches the same function but takes the byte branch at 14225, which is internally consistent, and I probed MID and MIDB from 1 to 5 with no panic. It is the same negative-index family as GHSA-fx5j-qcqg-grpf and GHSA-48hm-4h8j-58fg, though those are shared-string lookups in the reader rather than a unit mismatch in the formula library.

---

_Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai_
