Skip to content

ext/intl: Add SpoofChecker::getBidiSkeleton() - #23017

Merged
LamentXU123 merged 4 commits into
php:masterfrom
LamentXU123:icu-fea
Aug 4, 2026
Merged

ext/intl: Add SpoofChecker::getBidiSkeleton()#23017
LamentXU123 merged 4 commits into
php:masterfrom
LamentXU123:icu-fea

Conversation

@LamentXU123

@LamentXU123 LamentXU123 commented Aug 4, 2026

Copy link
Copy Markdown
Member

Follow up #13469. Since we have SpoofChecker::areBidiConfusable() with all these constant (UBIDI_LTR, UBIDI_RTL, UBIDI_MIXED and UBIDI_NEUTRAL) it can only determine whether two strings are visually confusable in a given text direction. Applications that need to detect confusable identifiers among a large existing set would otherwise need to repeatedly perform pairwise comparisons using areBidiConfusable().

Now since ICU 74+ and we have SpoofChecker::areBidiConfusable() already, it is convenient to add the corresponding SpoofChecker::areBidiConfusable() . ICU's bidi skeleton API transforms an identifier into a skeleton for a given text direction. So it is useful for larger compares.

e.g.

  $checker = new Spoofchecker();

  $skeleton = $checker->getBidiSkeleton(
      Spoofchecker::LTR,
      $identifier
  );

  if ($skeleton !== false && isset($knownSkeletons[$skeleton])) {
      // The identifier may be visually confusable with an existing one.
  }

The internal API is documented at: https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/uspoof_8h.html#a5aeeef353b4cca531b61480597a03e85

}

UnicodeString skeleton;
uspoof_getBidiSkeletonUnicodeString(

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.

why not uspoof_getBidiSkeletonUTF8 ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Correct, since PHP strings are already UTF-8 byte strings :)

#if __cplusplus >= 201703L
#include <string_view>
#include <unicode/unistr.h>
#include <unicode/uspoof.h>

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.

if you remove it, do you get a build error ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes. php_intl.h set U_SHOW_CPLUSPLUS_API to 0 so the declaration of uspoof_getBidiSkeletonUnicodeString() was hidden, even though ICU’s symbol-renaming macro still expanded the call to uspoof_getBidiSkeletonUnicodeString_74.

So I need to manually add this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

However, if we use the UTF8 API here, we can remove this.


var_dump($checker->getBidiSkeleton(Spoofchecker::LTR, "\x80"));
var_dump(intl_get_error_code() === U_INVALID_CHAR_FOUND);
?>

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.

nice to have

var_dump(
    $checker->getBidiSkeleton(Spoofchecker::LTR, "\u{05D0}A_1") ===
    $checker->getBidiSkeleton(Spoofchecker::LTR, "\u{05D0}1_A")
);
var_dump(
    $checker->getBidiSkeleton(Spoofchecker::RTL, "\u{05D0}A_1") ===
    $checker->getBidiSkeleton(Spoofchecker::RTL, "\u{05D0}1_A")
);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

RTL tests. Added.

Co-Authored-By: David CARLIER <devnexen@gmail.com>
@LamentXU123
LamentXU123 merged commit 9905878 into php:master Aug 4, 2026
18 checks passed
@LamentXU123
LamentXU123 deleted the icu-fea branch August 4, 2026 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants