Σで終わるUnicodeユーザー名でプロフィールページ読み込みエラーが発生

ユーザー関連のスラッグ(ユーザー名を含むもの)にも影響する可能性がありますか?
UTF-8 のユーザー名を使用しているユーザーが数人おり、一部のユーザーがプロフィールにアクセスできない状況です。

「いいね!」 2

ユーザーには全く影響はありません。ルートが完全に異なるためです。

プロフィールの読み込みに失敗するリンクを共有していただけますか?あるいは、バグをトリガーするユーザー名の例でも結構です。

「いいね!」 4

これは一つの例です:https://rembetiko.gr/u/σπυρος

ユーザー名は ΣΠΥΡΟΣ(σπυρος の大文字形)です


ギリシャ語で申し訳ありません :sweat_smile:

「いいね!」 2

このページは Cloudflare プロキシの背後にありますか?それをオフにしてテストできますか?

また、以下の設定の値は何ですか?

  • 許可された Unicode ユーザー名文字
  • Unicode ユーザー名
「いいね!」 3

値は以下の通りです(かなり標準的です :sweat_smile:

はい

プロキシを無効にして再度テストしました。残念ながら問題は解決しませんでした。もしよろしければ、ご自身でテストできるよう、しばらくプロキシを無効のままにしておきます :slight_smile:


ご協力いただき、誠にありがとうございます!:smiley:

「いいね!」 2

ふむ。

大文字で読み込もうとすると、最初は Προφίλ - ΣΠΥΡΟΣ - Ρεμπέτικο Φόρουμ が読み込まれますが、その後の小文字版への JSON フェッチで失敗します。

大文字と小文字の処理の間でエラーが発生しているようです。

「いいね!」 6

不思議なことに、これは動作します:

https://rembetiko.gr/u/αγγελικη_ντοτη

ユーザー名は ΑΓΓΕΛΙΚΗ_ΝΤΟΤΗ です(αγγελικη_ντοτη の大文字表記です)。

「いいね!」 2

ギリシャ語では、大文字の「Σ」を小文字にする方法が二つあるのでしょうか?

  • 語末で使用される場合の「ς」
  • それ以外の場所での「σ」
「いいね!」 2

これは間違っていますか?

[1] pry(main)> "ΣΠΥΡΟΣ".downcase
=> "σπυροσ"
「いいね!」 2

はい、文法的に誤っています。正しい形は「σπυρος」です。

「いいね!」 2

ああ、それは Ruby のバグのようです:

➜  ruby --version
ruby 3.0.0dev (2020-12-16T18:46:44Z master 93ba3ac036) [x86_64-linux]
➜  irb
irb(main):001:0> "ΣΠΥΡΟΣ".downcase
=> "σπυροσ"
「いいね!」 3

ただし、リンクが作成されればうまく動作しますね…つまり、何らかの方法で動作させることができるはずです…(?)

https://rembetiko.gr/u/σπυρος

「いいね!」 2

Ruby がユーザー名を文法的に正しい小文字版に変換しても、常に正規化されたユーザー名(Ruby では User.normalize_username)とデータベース内の username_lower でユーザーを検索していれば、問題にはなりません。

どの JSON フェッチが失敗しているのでしょうか?おそらく、ユーザー名の比較に異なるメカニズムを使用するルートが存在するのでしょう。

「いいね!」 4

もしかして、Ruby と JS の実装の違いが原因でしょうか?

➜  ruby --version           
ruby 3.0.0dev (2020-12-16T18:46:44Z master 93ba3ac036) [x86_64-linux]
➜  irb           
irb(main):001:0> "ΣΠΥΡΟΣ".downcase
=> "σπυροσ"
➜  node
Node.js v12.11.1 へようこそ。
詳細については ".help" と入力してください。
> "ΣΠΥΡΟΣ".toLowerCase()
'σπυρος'

私のテストでは、Firefox も NodeJS と同じ挙動を示します。

エンドポイント /u/#{username}.jsonusername_lower 列ではなく、ユーザー名列のみを返しています。そのため、ここではブラウザに依存しているのかもしれません。現在調査中です…

「いいね!」 6

ああ、それは困りましたね。問題はおそらくここにあるのでしょう:

クライアント側で行う代わりに、サーバー側の UserSerializerusername_lower を追加することを提案しようかと思いましたが、それでも username.toLowerCase の他のいくつかの出現箇所が残ってしまいます。

非 ASCII 文字を含む場合に username_lower をサーバー側で計算するために mini_racer を使う方が、より良い解決策なのかもしれませんね。:thinking:

「いいね!」 6

さて、回避策を追求するかに関わらず、これを Ruby に報告します。

「いいね!」 8

参考までに、PHP も Ruby と同じ方法で動作します。これは意図的な設計なのかもしれませんね (?)

コードはこちらでテストできます:

「いいね!」 1

興味深いことに、Postgres もここで失敗します:

[2] pry(main)> DB.query_single('select lower(?)', 'ΣΠΥΡΟΣ')
=> ["σπυροσ"]

おそらく、username_lower を計算する Discourse の内部メソッドで、この特異な挙動を特別に処理するべきでしょうか?

username_lower を呼び出すすべてのメソッドを見つけ、それらを中央の関数にパイプし、この特別ケースを許可するようにします(必要に応じてここで mini_racer を使用するか、単に .lower を呼び出してその後に sub で修正することもできます)。

わかりやすくするため、元の投稿のタイトルを更新しました。

「いいね!」 3

以下が前提です:

[4] pry(main)> "σπυρος".downcase
=> "σπυρος"

@chrispanag さんへの簡単な回避策として、ユーザー名を σπυρος に変更するだけで済みます。この場合、username と username_lower は完全に一致するため、そのまま問題なく動作します。

この特定のケースのためにコアに回避策を追加することには賛否ありますが、特に全く単純な回避策が存在する場合は慎重になるべきでしょう。

さらに、allowed unicode username characters 設定を使用して、ユーザー名での Σ の使用を禁止することも可能です。これにより、この問題が今後発生することはありません。

Ruby と Postgres の修正には全面的に賛成ですが、これらの問題を修正するには何年もかかる長い戦いとなっています。

「いいね!」 5

私も完全に同意します。私たちはアップストリームのバグを報告しており、Discourse ユーザーはそれまでの間、既存のツールを使って回避策を講じることができます。

「いいね!」 5