sm-commit AT lists.ibiblio.org
Subject: Source Mage code commit list
List archive
[[SM-Commit] ] GIT changes to master grimoire by Pavel Vinogradov (fadc9e226c41a2d050f335c02232806b56d689de)
- From: Pavel Vinogradov <scm AT sourcemage.org>
- To: sm-commit AT lists.ibiblio.org, sm-commit AT lists.sourcemage.org
- Subject: [[SM-Commit] ] GIT changes to master grimoire by Pavel Vinogradov (fadc9e226c41a2d050f335c02232806b56d689de)
- Date: Sun, 8 Nov 2026 04:32:31 +0000
GIT changes to master grimoire by Pavel Vinogradov <public AT sourcemage.org>:
devel/nodejs/HISTORY | 4
devel/nodejs/patches/node-v26.13.0-icu4c-79_fix-1.patch | 234
++++++++++++++++
2 files changed, 238 insertions(+)
New commits:
commit fadc9e226c41a2d050f335c02232806b56d689de
Author: Pavel Vinogradov <public AT sourcemage.org>
Commit: Pavel Vinogradov <public AT sourcemage.org>
devel/nodejs: fixed building with ICU 79
diff --git a/devel/nodejs/HISTORY b/devel/nodejs/HISTORY
index bdda819..c104e85 100644
--- a/devel/nodejs/HISTORY
+++ b/devel/nodejs/HISTORY
@@ -1,3 +1,7 @@
+2026-11-07 Pavel Vinogradov <public AT sourcemage.org>
+ * patches/node-v26.13.0-icu4c-79_fix-1.patch: added slightly modified
patch
+ from LFS project to fix building with ICU 79
+
2026-11-07 Ismael Luceno <ismael AT sourcemage.org>
* TRIGGERS: rebuild when simdjson is updated
* DEPENDS: require simdutf >= 9.3
diff --git a/devel/nodejs/patches/node-v26.13.0-icu4c-79_fix-1.patch
b/devel/nodejs/patches/node-v26.13.0-icu4c-79_fix-1.patch
new file mode 100644
index 0000000..185c494
--- /dev/null
+++ b/devel/nodejs/patches/node-v26.13.0-icu4c-79_fix-1.patch
@@ -0,0 +1,234 @@
+Submitted By: Joe Locash (jlocash at gmail dot com)
+Date: 2026-10-26
+Initial Package Version: 26.12.1
+Origin: Homebrew
+
https://raw.githubusercontent.com/Homebrew/homebrew-core/master/Patches/node/icu4c-79.patch
+Upstream Status: Unknown
+Description: Fixes building node.js with icu-79.x
+
+From e455d955bd6b7a7549106d1b9d7ae5bb3b9e77b4 Mon Sep 17 00:00:00 2001
+From: Jakob Linke <jgruber AT chromium.org>
+Date: Fri, 9 Oct 2026 12:41:30 +0200
+Subject: [PATCH] [regexp] Handle supplementary case equivalents of BMP
+ characters
+
+Unicode 18 adds U+1DF95, which simple-folds to U+00DF. This creates the
+first case-equivalence class spanning BMP and supplementary characters:
+{U+00DF, U+1E9E, U+1DF95}.
+
+Discard supplementary characters from the generator's non-unicode
+closures before calling Canonicalize, which requires UTF-16 code units
+and otherwise CHECK-fails with ICU 79. Apply the same filtering in
+runtime non-unicode closure.
+
+Generate SupplementaryEquivalentsSet and desugar its BMP characters into
+character classes under /iu and /iv, allowing literals to match
+surrogate pairs.
+
+Backreferences with differing UTF-16 character widths remain unsupported
+and are tracked in crbug.com/571793821.
+
+IgnoreSet is unchanged with ICU 78 and with ICU 78.2 patched to upstream
+Unicode 18 case data. With the patched data, the generator succeeds,
+SupplementaryEquivalentsSet is {U+00DF, U+1E9E}, and regexp tests pass
+in release and debug.
+
+Bug: 571232615, 571668686
+Change-Id: I9eacb273a74c66e17f0cfb1b256e863f2718c130
+Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8548134
+Reviewed-by: Patrick Thier <pthier AT chromium.org>
+Commit-Queue: Jakob Linke <jgruber AT chromium.org>
+Cr-Commit-Position: refs/heads/main@{#110522}
+---
+ src/regexp/gen-regexp-special-case.cc | 18 ++++++++++
+ src/regexp/regexp-parser.cc | 18 +++++++---
+ src/regexp/special-case.h | 47 ++++++++++++++++++++++++++-
+ 3 files changed, 77 insertions(+), 6 deletions(-)
+
+diff --git a/deps/v8/src/regexp/gen-regexp-special-case.cc
b/deps/v8/src/regexp/gen-regexp-special-case.cc
+index 86f6b212c93..98f70975be1 100644
+--- a/deps/v8/src/regexp/gen-regexp-special-case.cc
++++ b/deps/v8/src/regexp/gen-regexp-special-case.cc
+@@ -9,6 +9,7 @@
+
+ #include "src/base/strings.h"
+ #include "src/regexp/special-case.h"
++#include "unicode/uchar.h"
+
+ namespace v8 {
+ namespace internal {
+@@ -17,6 +18,19 @@ static const base::uc32 kSurrogateStart = 0xd800;
+ static const base::uc32 kSurrogateEnd = 0xdfff;
+ static const base::uc32 kNonBmpStart = 0x10000;
+
++// Removes supplementary code points from |set| and returns whether any were
++// present. Since Unicode 18, the case closure of a BMP character can
contain
++// supplementary code points (U+1DF95 LATIN SMALL LIGATURE LONG S WITH
++// DESCENDER S case-folds to U+00DF LATIN SMALL LETTER SHARP S). Non-unicode
++// ignoreCase matching compares UTF-16 code units, so a supplementary code
++// point never matches a BMP character and does not take part in
Canonicalize.
++bool RemoveSupplementary(icu::UnicodeSet& set) {
++ constexpr UChar32 kFirstSupplementary =
static_cast<UChar32>(kNonBmpStart);
++ if (!set.containsSome(kFirstSupplementary, UCHAR_MAX_VALUE)) return false;
++ set.remove(kFirstSupplementary, UCHAR_MAX_VALUE);
++ return true;
++}
++
+ // The following code generates "src/regexp/special-case.cc".
+ void PrintSet(std::ofstream& out, const char* name,
+ const icu::UnicodeSet& set) {
+@@ -51,6 +65,7 @@ void PrintSpecial(std::ofstream& out) {
+ icu::UnicodeSet current;
+ icu::UnicodeSet special_add;
+ icu::UnicodeSet ignore;
++ icu::UnicodeSet supplementary_equivalents;
+ UErrorCode status = U_ZERO_ERROR;
+ icu::UnicodeSet upper("[\\p{Lu}]", status);
+ CHECK(U_SUCCESS(status));
+@@ -63,6 +78,7 @@ void PrintSpecial(std::ofstream& out) {
+ }
+ current.set(i, i);
+ current.closeOver(USET_CASE_INSENSITIVE);
++ if (RemoveSupplementary(current)) supplementary_equivalents.add(i);
+
+ // Check to see if all characters in the case-folding equivalence
+ // class as defined by UnicodeSet::closeOver all map to the same
+@@ -112,6 +128,7 @@ void PrintSpecial(std::ofstream& out) {
+ UChar32 canonical = RegExpCaseFolding::Canonicalize(c);
+ current.set(c, c);
+ current.closeOver(USET_CASE_INSENSITIVE);
++ RemoveSupplementary(current);
+ current.removeAll(ignore);
+ for (int32_t j = 0; j < current.getRangeCount(); j++) {
+ for (UChar32 c2 = current.getRangeStart(j);
+@@ -124,6 +141,7 @@ void PrintSpecial(std::ofstream& out) {
+
+ PrintSet(out, "IgnoreSet", ignore);
+ PrintSet(out, "SpecialAddSet", special_add);
++ PrintSet(out, "SupplementaryEquivalentsSet", supplementary_equivalents);
+ }
+
+ void WriteHeader(const char* header_filename) {
+diff --git a/deps/v8/src/regexp/regexp-parser.cc
b/deps/v8/src/regexp/regexp-parser.cc
+index 2792cd0f1e9..dd883c3eddc 100644
+--- a/deps/v8/src/regexp/regexp-parser.cc
++++ b/deps/v8/src/regexp/regexp-parser.cc
+@@ -10,6 +10,7 @@
+ #include "src/regexp/regexp-ast.h"
+ #include "src/regexp/regexp-macro-assembler.h"
+ #include "src/regexp/regexp.h"
++#include "src/regexp/special-case.h"
+ #include "src/strings/char-predicates-inl.h"
+ #include "src/utils/ostreams.h"
+ #include "src/utils/utils.h"
+@@ -156,6 +157,10 @@ void RegExpTextBuilder::FlushText() {
+
+ void RegExpTextBuilder::AddCharacter(base::uc16 c) {
+ FlushPendingSurrogate();
++ if (NeedsDesugaringForIgnoreCase(c)) {
++ AddClassRangesForDesugaring(c);
++ return;
++ }
+ if (characters_ == nullptr) {
+ characters_ = zone()->New<ZoneList<base::uc16>>(4, zone());
+ }
+@@ -238,15 +243,18 @@ bool
RegExpTextBuilder::NeedsDesugaringForUnicode(RegExpClassRanges* cc) {
+ return false;
+ }
+
+-// We only use this for characters made of surrogate pairs. All other
+-// characters outside of character classes are made case independent in the
+-// code generation.
++// Desugar supplementary characters with case equivalents and BMP characters
++// with supplementary equivalents. Other atoms are folded during code
++// generation.
+ bool RegExpTextBuilder::NeedsDesugaringForIgnoreCase(base::uc32 c) {
+ #ifdef V8_INTL_SUPPORT
+ if (IsUnicodeMode() && ignore_case()) {
++ if (c <= unibrow::Utf16::kMaxNonSurrogateCharCode) {
++ return RegExpCaseFolding::HasSupplementaryEquivalents(
++ static_cast<base::uc16>(c));
++ }
+ icu::UnicodeSet set(c, c);
+- set.closeOver(USET_CASE_INSENSITIVE);
+- set.removeAllStrings();
++ RegExpCaseFolding::CloseOver(set, RegExpCaseFolding::Mode::kUnicode);
+ return set.size() > 1;
+ }
+ // In the case where ICU is not included, we act as if the unicode flag is
+diff --git a/deps/v8/src/regexp/special-case.h
b/deps/v8/src/regexp/special-case.h
+index 753c9231ede..80b88a308cc 100644
+--- a/deps/v8/src/regexp/special-case.h
++++ b/deps/v8/src/regexp/special-case.h
+@@ -7,8 +7,8 @@
+
+ #ifdef V8_INTL_SUPPORT
+ #include "src/base/logging.h"
++#include "src/base/strings.h"
+ #include "src/common/globals.h"
+-
+ #include "unicode/uchar.h"
+ #include "unicode/uniset.h"
+ #include "unicode/unistr.h"
+@@ -71,9 +71,17 @@ namespace internal {
+ // another character. Characters that match no other characters in
+ // their equivalence class are added to IgnoreSet. Characters that
+ // match at least one other character are added to SpecialAddSet.
++// Supplementary code points are ignored throughout: non-unicode matching
++// compares UTF-16 code units, so they can never match a BMP character.
++//
++// The generator additionally emits SupplementaryEquivalentsSet, the BMP
++// characters whose Unicode case closure contains supplementary code points.
++// This set is used for unicode-mode matching, see
HasSupplementaryEquivalents.
+
+ class RegExpCaseFolding final : public AllStatic {
+ public:
++ enum class Mode { kNonUnicode, kUnicode };
++
+ static const icu::UnicodeSet& IgnoreSet();
+ static const icu::UnicodeSet& SpecialAddSet();
+
+@@ -108,6 +116,43 @@ class RegExpCaseFolding final : public AllStatic {
+ // h. Return cu.
+ return cu;
+ }
++
++ // Close a set of characters under case equivalence, preserving its
++ // original members. Non-unicode inputs must be UTF-16 code units.
++ static void CloseOver(icu::UnicodeSet& set, Mode mode) {
++ if (mode == Mode::kUnicode) {
++ set.closeOver(USET_SIMPLE_CASE_INSENSITIVE);
++ return;
++ }
++ DCHECK(!set.containsSome(0x10000, 0x10ffff));
++ if (IgnoreSet().containsNone(set)) {
++ CloseOverNonUnicode(set);
++ return;
++ }
++ if (IgnoreSet().containsAll(set)) return;
++ // Ignored characters neither contribute nor acquire equivalents, but
++ // must remain in the result if they were explicitly present.
++ icu::UnicodeSet ignored(set);
++ ignored.retainAll(IgnoreSet());
++ set.removeAll(IgnoreSet());
++ CloseOverNonUnicode(set);
++ set.addAll(ignored);
++ }
++
++ // Whether c has supplementary Unicode case equivalents.
++ static bool HasSupplementaryEquivalents(base::uc16 c) {
++ return SupplementaryEquivalentsSet().contains(c);
++ }
++
++ private:
++ static const icu::UnicodeSet& SupplementaryEquivalentsSet();
++
++ // Requires a set containing no IgnoreSet characters.
++ static void CloseOverNonUnicode(icu::UnicodeSet& set) {
++ set.closeOver(USET_SIMPLE_CASE_INSENSITIVE);
++ set.removeAll(IgnoreSet());
++ set.remove(0x10000, 0x10ffff);
++ }
+ };
+
+ } // namespace internal
- [[SM-Commit] ] GIT changes to master grimoire by Pavel Vinogradov (fadc9e226c41a2d050f335c02232806b56d689de), Pavel Vinogradov, 11/07/2026
Archive powered by MHonArc 2.6.24.