Nome de usuário Unicode com Σ como caractere final causa erro ao carregar página de perfil

Isso também pode afetar os slugs relacionados aos usuários? (contendo o nome de usuário)
Temos alguns usuários que usam nomes de usuário em UTF-8 e alguns deles não conseguem acessar seus perfis…

2 curtidas

Isso não deve afetar o usuário de forma alguma, pois as rotas são completamente diferentes.

Você pode compartilhar um link onde um perfil falha ao carregar? Ou, pelo menos, um exemplo de nome de usuário que dispara o bug?

4 curtidas

Este é um caso: https://rembetiko.gr/u/σπυρος

O nome de usuário é ΣΠΥΡΟΣ (que é a forma maiúscula de σπυρος)


Desculpe pelo grego :sweat_smile:

2 curtidas

Esta página está atrás de um proxy do Cloudflare? Você pode testar com isso desativado?

Além disso, quais são os valores das configurações:

  • caracteres unicode permitidos para nomes de usuário

  • nomes de usuário unicode

3 curtidas

Aqui estão os valores (bastante padrão :sweat_smile:)

Sim

Acabei de desativar o proxy e testei novamente. Infelizmente, o problema persiste. Vou manter o proxy desativado por um tempo para que você possa testá-lo se quiser :slight_smile:


Muito obrigado pela sua ajuda! :smiley:

2 curtidas

Hmmmm.

Se eu tentar carregar a versão maiúscula, ele carrega: Προφίλ - ΣΠΥΡΟΣ - Ρεμπέτικο Φόρουμ inicialmente e depois falha em uma busca JSON subsequente para a versão minúscula.

Parece ser um erro no tratamento de maiúsculas/minúsculas entre nós.

6 curtidas

Estranhamente, este funciona:

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

O nome de usuário é ΑΓΓΕΛΙΚΗ_ΝΤΟΤΗ (novamente a forma maiúscula de αγγελικη_ντοτη)

2 curtidas

Será que, em grego, há duas formas de transformar a letra ‘Σ’ em minúscula?

  • ‘ς’ quando é usada no final de uma palavra
  • ‘σ’ em qualquer outro lugar
2 curtidas

Então isso está errado?

[1] pry(main)> "ΣΠΥΡΟΣ".downcase
=> "σπυροσ"
2 curtidas

Sim, gramaticalmente está errado. A forma correta é “σπυρος”.

2 curtidas

Ah, então receio que seja um bug do Ruby:

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

Mas funciona bem quando o link é criado… Então deve haver uma maneira de fazê-lo funcionar… (?)

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

2 curtidas

Não deveria importar se o Ruby converte o nome de usuário na versão em minúsculas gramaticalmente correta, desde que ele sempre pesquise usuários com o nome de usuário normalizado (User.normalize_username no Ruby) e o username_lower no banco de dados.

Qual requisição JSON falha? É bastante provável que haja uma rota que use um mecanismo diferente para comparar nomes de usuário.

4 curtidas

Talvez seja porque Ruby e JS tenham implementações diferentes?

➜  ruby --version           
ruby 3.0.0dev (2020-12-16T18:46:44Z master 93ba3ac036) [x86_64-linux]
➜  irb           
irb(main):001:0> "ΣΠΥΡΟΣ".downcase
=> "σπυροσ"
➜  node
Welcome to Node.js v12.11.1.
Type ".help" for more information.
> "ΣΠΥΡΟΣ".toLowerCase()
'σπυρος'

No Firefox, o comportamento é o mesmo do NodeJS nos meus testes.

O endpoint /u/#{username}.json retorna apenas a coluna username e não a coluna username_lower, então talvez estejamos dependendo do navegador aqui? Investigando agora…

6 curtidas

Oh, isso é ruim. Então, o problema provavelmente é este:

Eu ia sugerir adicionar o username_lower ao UserSerializer no servidor em vez de fazer isso no cliente, mas isso ainda nos deixaria com algumas outras ocorrências de username.toLowerCase.

Fico me perguntando se a melhor solução seria usar o mini_racer para calcular o username_lower no servidor quando ele contiver caracteres não ASCII. :thinking:

6 curtidas

Bem, independentemente da solução alternativa que estamos perseguindo, vou reportar isso ao Ruby.

8 curtidas

Só para referência, o PHP faz da mesma forma que o Ruby… Isso me faz pensar que é um design intencional (?)

Você pode testar o código aqui:

1 curtida

Curiosamente, o Postgres também falha aqui:

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

Talvez devêssemos simplesmente tratar esse comportamento peculiar como um caso especial em nosso método interno do Discourse que calcula o username_lower?

Encontre todos os métodos que chamam username_lower, encadeie-os a uma função central e, em seguida, permita esse caso especial (acho que podemos usar uma chamada ao mini_racer aqui, se quisermos, ou simplesmente chamar .lower e corrigi-la depois com uma chamada a sub).

Atualizei o título do OP aqui para deixar mais claro.

3 curtidas

Dado:

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

@chrispanag uma solução alternativa trivial para você é simplesmente alterar o nome de usuário para σπυρος; o nome de usuário e o username_lower serão exatamente iguais, e isso funcionará perfeitamente.

Estou dividido quanto a adicionar soluções alternativas ao núcleo apenas para este caso específico, especialmente quando existe uma solução alternativa totalmente trivial.

Além disso, você poderia proibir o uso de Σ em nomes de usuário usando nossa configuração allowed unicode username characters, o que garantiria que esse problema nunca mais ocorra.

Estou totalmente a favor de corrigir o Ruby e o Postgres aqui, mas essa é uma batalha longa de vários anos para resolver esses problemas.

5 curtidas

Concordo plenamente. Nós relatamos os bugs para os mantenedores dos projetos upstream e os usuários do Discourse podem usar ferramentas existentes para contornar o problema enquanto isso.

5 curtidas