Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129000 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 59C8C1A00BC for ; Wed, 29 Oct 2025 16:56:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1761756984; bh=jkv2Qpy4kuBUQsoa1DwshHGGFS7f/jAdtDkRWXvKyTg=; h=From:Date:Subject:To:From; b=dO6xEXOthxRj2fz+O8hO1smLiwyeH4fEs6aC+vZkZUhPpqJcxXp+tz9jrk0ZPOsjw vNCmHgpf5wdIIxJGqemQmeNIlWLqb6lahTLiU0KjQMFiBH5Eul6Vx8Hk2D0SCU1fWH XfFp/ILbR9wMTgucOb93dHsVgRc3Ad2GFtQb8oh91EkUMksPtSlxKD0EeCcyBquI+W R13cd9DzzI8gXmmrsGHnKFp0RQmVx8sdi5WVFx7XyS93JcTYDtiVL5kJZCdNttqcmP PDY9o/1+HhdjAf1lXTnT1oDdQ7/SOTDNmLXLe0qjWwsoT0HkNDbc+S3A27nLqUgQtX UskD/AsTd3lTA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 2C2111801D5 for ; Wed, 29 Oct 2025 16:56:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-yx1-f45.google.com (mail-yx1-f45.google.com [74.125.224.45]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 29 Oct 2025 16:56:23 +0000 (UTC) Received: by mail-yx1-f45.google.com with SMTP id 956f58d0204a3-63e3568f90dso208627d50.0 for ; Wed, 29 Oct 2025 09:56:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intuitivetechnology.com; s=google; t=1761756978; x=1762361778; darn=lists.php.net; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=jkv2Qpy4kuBUQsoa1DwshHGGFS7f/jAdtDkRWXvKyTg=; b=ANoDk/2yIrt6gTkXfhMP0HdeDa89qNxWQqyOSeTBWfoqAKRh+n/fdjyu5l/oeVoUKG Effs0QwhQTbtyYrAnIFel+ZkRIZTTyioOjrEF+zYcydRR6rmLjAE2SeoaC0L/TGaxuSu 76T6QYfMUHgiuiWv79zm4KMj2WawEsYB9AUhDGiPoMj6sd2wqnUJ+6jBu2LHcSfAvMQg uwvVtyFNI5Q3DFKio7mhRc5tWgMI0PAXD425vJAykAVBxjZRdN1EM+BHRWKYwbC0h+1z cYJheKGuuKaUs86hkXj00NZqDXTRaog3Er2Zc99IWGWsn4X+uvrT6ZDZYuu8fqS6rfDD IqVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761756978; x=1762361778; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=jkv2Qpy4kuBUQsoa1DwshHGGFS7f/jAdtDkRWXvKyTg=; b=dkDPFttN9zcj6/IHF2qtNKRC8240CMVSnRyF2NQEGD7WjvtqqPti5hPebBM+Up5oRf XVEekq3KipL3q9O2JR1mTekPQScYI6ZRe6kl6tBLzZXk85lqvgVHPJE8jmuowjEhvYfT Ubu4mbHyLVh0HYbsnt73QrsavqEbjD1gOOq0C19QBSYfZ+iiexPmxko3y2nHMtBsifZy vJfbehQn0fHI+X7qQGqzs5k4asLB+jHxYLwhTyHXJNpye9AsiLtCDO/TYuEf1k75FpI/ iqdXlu970xUGNo6kodb+hy9O8Dwgn8xTYzi8Jkhwl/hXF846LzhCCmhyh+RU1Ba1gDMg KPKw== X-Gm-Message-State: AOJu0Yzfk6B2CKQkHd0JYPpGjXZtOkrjI+c/QMFYUJwyxBCMhTs3hvoe PWHgVO5ZG+Env0ao1yK1O/TRckNtHImGpA8c/pIdrTP6VSDkF9ia83+DsUwz77ZL/YFTdt6cee3 Fp3+VxAucQdqkXMuUaVInwSkOxdsr9TdZbj7Fayustd80ceeynVBxBk0= X-Gm-Gg: ASbGnct0pYPamoby7ElacJTg+3eKuaVoHhvVczRKEEQ+DA5wo0yzFRcwXx+6gmol0QC sGkZNp7jpu2Doz1W4brUA6LAQV4HNTcHRDgSRmG4Qx0ePLjcufRN1TunlhUwQG3ooYQsjVnbD5K dfkwNOgxLrerB034qw5TF40GUqGUT4yHOptnQaXxtR8VeSSk8Wg+al6Mjdy8YVaTR7Rv7I9jp9T 9Kp20EDYIkNjLu3cmmRzz75zAUHlrBoM+isIS03fLd0NY7OVOPGFMkH5oOXTw== X-Google-Smtp-Source: AGHT+IFj9BcHi7gjfurd+hWzBDem5oV4wJ3jEdxpgwgqA1rCq0VGxJxRwZutKTWLWzxcYpTmxPkinLGoOsoy1Nb+JNY= X-Received: by 2002:a05:690c:6c84:b0:784:f14d:6946 with SMTP id 00721157ae682-78628ffec19mr33743697b3.55.1761756977779; Wed, 29 Oct 2025 09:56:17 -0700 (PDT) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 Date: Wed, 29 Oct 2025 09:56:07 -0700 X-Gm-Features: AWmQ_bnYSevjoRY_G6PCdm41AZUjqf9tunH2rj9Ek5HRTfQAhndNN1eXzzQoIfE Message-ID: Subject: [PHP-DEV] Review request: Enabling `transitive_compare_mode` to fix SORT_REGULAR To: PHP internals Content-Type: multipart/alternative; boundary="000000000000d7656006424f0224" From: jmarble@intuitivetechnology.com (Jason Marble) --000000000000d7656006424f0224 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hello PHP Internals! I believe I've found an acceptable solution to the issue that's plagued SORT_REGULAR since the dawn of time. Fundamentally, all sorting algorithms require transitive comparisons (if A =E2=89=A4 B and B =E2=89=A4 C, then A =E2=89=A4 C). However, PHP's SORT_REG= ULAR comparison function violates transitivity when mixing numeric strings, non-numeric strings, and numbers, leading to unpredictable and non-deterministic sort results. **The Solution:** Add a `transitive_compare_mode` flag to executor_globals (TLS) that signals zendi_smart_strcmp() to enforce consistent ordering during SORT_REGULAR operations: - Numeric strings are consistently ordered relative to non-numeric strings - Eliminates circular comparisons - Maintains PHP 8+ semantics (numeric-types < numeric-strings < non-numeric= ) **Implementation:** - PR: https://github.com/php/php-src/pull/20315 - Uses save/restore pattern for reentrancy safety - New test coverage included **Historical Context:** Raghubansh Kumar documented this issue in 2007, creating tests with the note "(OK to fail as result is unpredectable)". Nikita Popov's 2019 RFC improved string-to-number comparison semantics but didn't eliminate the transitivity violation. This fix completes that work. **Test Results:** Four variation11 tests currently fail as expected, but their outputs are now deterministic and more "sane" than both the 2007 and 2019 versions imo: https://gist.github.com/jmarble/957a096cb2bf25b577de47449305723f **ABI Considerations:** This adds a field to _zend_executor_globals, which is technically an ABI break appropriate for PHP 8.6. However, practical impact is minimal, I think, since most extensions access executor_globals through the EG() macro (which abstracts the struct layout), not via direct struct manipulation. I'd appreciate review and feedback on this approach. This is a long-standing correctness issue. Thank you for your time and consideration! - Jason --000000000000d7656006424f0224 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello PHP Internals!

I belie= ve I've found an acceptable solution to the issue that's plagued SO= RT_REGULAR since the dawn of time.

Fundamentally, = all sorting algorithms require transitive comparisons (if A =E2=89=A4 B and= B =E2=89=A4 C, then A =E2=89=A4 C). However, PHP's SORT_REGULAR compar= ison function violates transitivity when mixing numeric strings, non-numeri= c strings, and numbers, leading to unpredictable and non-deterministic sort= results.

**The Solution:**
Add a `transitive_c= ompare_mode` flag to executor_globals (TLS) that signals zendi_smart_strcmp= () to enforce consistent ordering during SORT_REGULAR operations:
- Nume= ric strings are consistently ordered relative to non-numeric strings
- E= liminates circular comparisons
- Maintains PHP 8+ semantics (numeric-typ= es < numeric-strings < non-numeric)

**Implem= entation:**
- PR: = https://github.com/php/php-src/pull/20315
- Uses save/restore patter= n for reentrancy safety
- New test coverage included

**Historical Context:**
Raghubansh Kumar documented this issue in = 2007, creating tests with the note "(OK to fail as result is unpredect= able)". Nikita Popov's 2019 RFC improved string-to-number comparis= on semantics but didn't eliminate the transitivity violation. This fix = completes that work.

**Test Results:**
Four var= iation11 tests currently fail as expected, but their outputs are now determ= inistic and more "sane" than both the 2007 and 2019 versions imo:=
https://gist.github.com/jmarble/957a096cb2bf25b577de47449305723f<= /div>

**ABI Considerations:**
This adds a field to _z= end_executor_globals, which is technically an ABI break appropriate for PHP= 8.6. However, practical impact is minimal, I think, since most extensions = access executor_globals through the EG() macro (which abstracts the struct = layout),
not via direct struct manipulation.

I&= #39;d appreciate review and feedback on this approach. This is a long-stand= ing correctness issue.

Thank you for your time and consideration!

- Jason
--000000000000d7656006424f0224--