Nombre de usuario Unicode con Σ como carácter final provoca un error al cargar la página de perfil

¿Esto también puede afectar a los identificadores (slugs) relacionados con usuarios (que contienen el nombre de usuario)?
Tenemos varios usuarios que utilizan nombres de usuario en UTF-8 y algunos no pueden acceder a sus perfiles…

2 Me gusta

No debería afectar al usuario en absoluto, ya que las rutas son completamente diferentes.

¿Puedes compartir un enlace donde un perfil no se cargue? O al menos un ejemplo de un nombre de usuario que active el error?

4 Me gusta

Este es un caso: https://rembetiko.gr/u/σπυρος

El nombre de usuario es ΣΠΥΡΟΣ (que es la forma mayúscula de σπυρος)


Perdón por el griego :sweat_smile:

2 Me gusta

¿Esta página está detrás de un proxy de Cloudflare? ¿Puedes probarlo con esa opción desactivada?

También, ¿cuáles son los valores de la configuración:

  • caracteres unicode permitidos en nombres de usuario

  • nombres de usuario unicode?

3 Me gusta

Aquí están los valores (bastante estándar :sweat_smile:)

Acabo de desactivar el proxy y volver a probar. Por desgracia, el problema persiste. Mantendré el proxy desactivado un rato para que puedas probarlo tú mismo si lo deseas :slight_smile:


¡Muchas gracias por tu ayuda! :smiley:

2 Me gusta

Hmmm.

Si intento cargar la versión en mayúsculas, primero carga: Προφίλ - ΣΠΥΡΟΣ - Ρεμπέτικο Φόρουμ y luego falla en una solicitud JSON posterior a la versión en minúsculas.

Parece ser un error en nuestra gestión de mayúsculas y minúsculas.

6 Me gusta

Curiosamente, este sí funciona:

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

El nombre de usuario es ΑΓΓΕΛΙΚΗ_ΝΤΟΤΗ (de nuevo, la forma en mayúsculas de αγγελικη_ντοτη)

2 Me gusta

¿Podría ser que en griego haya dos formas de poner la letra ‘Σ’ en minúscula?

  • ‘ς’ cuando se usa al final de una palabra
  • ‘σ’ en cualquier otro lugar
2 Me gusta

¿Entonces esto está mal?

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

Sí, gramaticalmente es incorrecto. La forma correcta debería ser “σπυρος”.

2 Me gusta

Oh, temo que eso es un error de Ruby:

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

Pero funciona bien cuando se crea el enlace… Así que debe haber una forma de que funcione… (?)

2 Me gusta

No debería importar si Ruby convierte el nombre de usuario en la versión en minúsculas gramaticalmente correcta, siempre que siempre busque a los usuarios con el nombre de usuario normalizado (User.normalize_username en Ruby) y con username_lower en la base de datos.

¿Qué solicitud JSON falla? Es muy probable que exista una ruta que utilice un mecanismo diferente para comparar nombres de usuario.

4 Me gusta

¿Quizás se debe a que Ruby y JS tienen implementaciones distintas?

➜  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()
'σπυρος'

Firefox hace lo mismo que NodeJS en mis pruebas.

El endpoint /u/#{username}.json solo devuelve la columna de nombre de usuario y no la columna username_lower, así que ¿quizás estamos dependiendo del navegador? Lo estoy investigando ahora…

6 Me gusta

Oh, eso es malo. Así que, el problema probablemente sea esto:

Pensaba sugerir agregar username_lower al UserSerializer en el servidor en lugar de hacerlo en el cliente, pero esto aún nos dejaría con un par de otras ocurrencias de username.toLowerCase.

Me pregunto si la mejor solución sería usar mini_racer para calcular username_lower en el servidor cuando contiene caracteres no ASCII. :thinking:

6 Me gusta

Bueno, independientemente de la solución temporal que estemos buscando, informaré sobre esto a Ruby.

8 Me gusta

Solo como referencia, PHP lo hace de la misma manera que Ruby… Me hace pensar que es un diseño intencional (?)

Puedes probar el código aquí:

1 me gusta

Curiosamente, Postgres también falla aquí:

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

¿Quizás deberíamos simplemente tratar este comportamiento como un caso especial en nuestro método interno de Discourse que se encarga de calcular username_lower?

Encuentra todos los métodos que llaman a username_lower, redirígelos a una función central y luego permite este caso especial (supongo que podemos usar una llamada a mini_racer si lo deseamos o simplemente llamar a .lower y corregirlo después con una llamada a sub).

Actualizando el título del OP aquí para que sea más claro.

3 Me gusta

Dado:

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

@chrispanag, una solución trivial para ti es simplemente cambiar el nombre de usuario a σπυρος; el nombre de usuario y username_lower serán exactamente iguales y esto funcionará perfectamente.

Estoy indeciso sobre agregar soluciones temporales al núcleo solo para este caso específico, especialmente cuando existe una solución trivial.

Adicionalmente, podrías prohibir el uso de Σ en los nombres de usuario mediante la configuración allowed unicode username characters, lo que garantizaría que este problema nunca vuelva a aparecer.

Estoy totalmente a favor de corregir Ruby y Postgres aquí, pero esta es una batalla larga de varios años para lograr que se solucionen estos problemas.

5 Me gusta

Estoy totalmente de acuerdo; informamos sobre los errores aguas arriba y los usuarios de Discourse pueden utilizar herramientas existentes para encontrar soluciones alternativas mientras tanto.

5 Me gusta