zh99998 / discourse-username-localization

Localized username support.
GNU Affero General Public License v3.0
14 stars 16 forks source link

怎么不用 ruby 原生的 CJK 检测呀 #3

Open marguerite opened 7 years ago

marguerite commented 7 years ago
    str =~ /\p{Han}|\p{Katakana}|\p{Hiragana}|\p{Hangul}/)

另外,那个 USERNAME_ROUTE_FORMAT 看起来像是可以 override 的,它写了 unless defined?

就是不知道玲奈的 plugin 是在它之前还是之后运行...

zh99998 commented 7 years ago

因为还有 js 也需要用这个,那套巨长无比的正则总归还是要有的,单把ruby的部分拿出来意义也不大

当然,你如果对这个有执念的话可以发个pr...

此外,我不是太熟悉discourse的插件机制,按理说我用 sed 修改的部分,直接用插件提供的接口应该是也能实现的,从而可以避免破坏文件。但是我并不知道该怎样做,因为这个一直能用就没折腾了.... 如果你会改的话也可以发个pr...


啊啊啊啊啊啊啊原来是苏姐姐!我去改!

zh99998 commented 7 years ago

目前研究情况:

  1. USERNAME_ROUTE_FORMAT 确实可以 override 的,测试成功。

  2. locales 可以直接用放一个文件的办法来改

  3. es6 怎么改还是没搞定,之前听 @fantasticfears 说可以通路径放一个文件的办法来覆盖,但是测试没成功。。。

  4. 关于原生CJK检测,如何查到这几组分别对应哪些字符范围?

关于前面三点尝试做的改动放到了测试分支 test 中

marguerite commented 7 years ago

es6 我也不熟悉了...

那个对应字符目前我也不知道,不过可以把你那个长串的 start 和 end 分别扔 irb 里面试一下嘛:

    irb -E UTF-8
    p /上面那一堆/.match(unicode string)

这是官方的 Regexp 类的实现,我只知道用了它肯定能更容易让 discourse 上游接受...

https://ruby-doc.org/core-2.1.1/Regexp.html

marguerite commented 7 years ago

找到了:http://www.unicode.org/Public/UNIDATA/Scripts.txt

好像有人研究过这个:http://qiita.com/ymrl/items/b34c5493c9383633330b

zh99998 commented 7 years ago

刚才通过match,发现这个表跟我之前的是不一致的,然后这个表是更【正确】的,我之前是按照代码区指定的,而这个能精确到字符

例如说

1B000、1B001是在的,而往后直到 1B0FF 都不在。 我之前的表,是 1B000-1B0FF 都在。 实际分配来说,1B000、1B001是两个字符,而往后是已经分配给 CJK 代码区的、但是尚未分配的字符

............... 然而到了 js 那边 ................................

zh99998 commented 7 years ago

想到一个办法,跑穷举所有unicode。

marguerite commented 7 years ago

@zh99998 所以我更厉害一些 233

ember js 的我找到了这个:

https://meta.discourse.org/t/how-to-override-an-existing-handlebars-template-from-plugin-part-ii/12245

上面那个文章的内容我看不懂(不懂 JS),不过看到里面有在讲 override javascript 什么的,然后有人提到了这个项目:

https://github.com/discoursehosting/discourse-adsense

里面应该是有 override 的代码吧,摊手

marguerite commented 7 years ago

ruby regexp 的实现是用了一个 C 的引擎...https://github.com/k-takata/Onigmo

所以肯定要比单 regex 好一些。

zh99998 commented 7 years ago

写了个穷举unicode的脚本,性能还不错,几秒钟就能跑完,于是大概可以真的用进install脚本里去。。

#encoding: UTF-8

inrange = false
result = []

0x110000.times do |codepoint|
    begin
        char = codepoint.chr Encoding::UTF_8
    rescue Encoding::CompatibilityError, Encoding::InvalidByteSequenceError, RangeError
        next
    end
    if inrange ^ /\p{Han}|\p{Katakana}|\p{Hiragana}|\p{Hangul}/.match(char)
        if inrange
            result.push codepoint - 1
        else
            result.push codepoint
        end
        inrange = !inrange
    end
end
result.each_with_index do |codepoint, index|
    print "\\u{#{codepoint.to_s(16).upcase}}"
    if index % 2 == 0 # range begin
        print '-'
    end
end

跑出来的结果是

\u{1100}-\u{11FF}\u{2E80}-\u{2E99}\u{2E9B}-\u{2EF3}\u{2F00}-\u{2FD5}\u{3005}-\u{3005}\u{3007}-\u{3007}\u{3021}-\u{3029}\u{302E}-\u{302F}\u{3038}-\u{303B}\u{3041}-\u{3096}\u{309D}-\u{309F}\u{30A1}-\u{30FA}\u{30FD}-\u{30FF}\u{3131}-\u{318E}\u{31F0}-\u{321E}\u{3260}-\u{327E}\u{32D0}-\u{32FE}\u{3300}-\u{3357}\u{3400}-\u{4DB5}\u{4E00}-\u{9FD5}\u{A960}-\u{A97C}\u{AC00}-\u{D7A3}\u{D7B0}-\u{D7C6}\u{D7CB}-\u{D7FB}\u{F900}-\u{FA6D}\u{FA70}-\u{FAD9}\u{FF66}-\u{FF6F}\u{FF71}-\u{FF9D}\u{FFA0}-\u{FFBE}\u{FFC2}-\u{FFC7}\u{FFCA}-\u{FFCF}\u{FFD2}-\u{FFD7}\u{FFDA}-\u{FFDC}\u{1B000}-\u{1B001}\u{1F200}-\u{1F200}\u{20000}-\u{2A6D6}\u{2A700}-\u{2B734}\u{2B740}-\u{2B81D}\u{2B820}-\u{2CEA1}\u{2F800}-\u{2FA1D}

验证中....

erickguan commented 7 years ago

@marguerite 好久不见苏姐了!Discourse 官方不只担心 Unicode CJK 的字符,倒是更担心和 IDN homograph attack 一样的问题,就是怎么排除看起来相似的字符。

marguerite commented 7 years ago

看起来相似但毕竟不是同一个啊。难道同一个论坛里有人冒充管理员你还发现不了么,我觉得用户名跟这个没关系,再说这个问题英文又不是没有,大些的 I 和小写的 L 就可以,我觉得官方肯定自己都没有写过这种排除代码

marguerite commented 7 years ago

https://github.com/discourse/discourse-solved/blob/master/assets/javascripts/discourse/pre-initializers/extend-category-for-solved.js.es6

好像这个确定是扩展已有的 es6 的...不知道能不能用来替换用户名

marguerite commented 7 years ago

https://meta.discourse.org/t/brand-new-plugin-interface 快来看看这个,真的可以复写单个函数哎

cxgreat2014 commented 7 years ago

......貌似开启这个插件之后。。。嗯。。准确的说还是discourse国际化的锅,貌似不知道是常发还是偶发忘记密码重置邮件链接点击无法重置密码,以及站点的/discobot/certificate.svg?date=Jun+11+2017&user_id=+user_id那幅图片无法显示。。。

marguerite commented 7 years ago

@zh99998 快出来!我们社区的郭云鹤改了 es6 版本的,目前 hashtag 他不知道是做什么的就还没改,你快告诉他是做什么的:https://github.com/openSUSE-zh/discourse-username-localization

zh99998 commented 7 years ago

啊啊啊啊赞,来hangouts/telegram说? +神楽坂玲奈zh99998@gmail.com / @zh99998

2017-09-02 9:25 GMT+08:00 Marguerite Su notifications@github.com:

@zh99998 https://github.com/zh99998 快出来!我们社区的郭云鹤改了 es6 版本的,目前 hashtag 他不知道是做什么的就还没改,你快告诉他是做什么的:https://github.com/openSUSE-zh/ discourse-username-localization

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/zh99998/discourse-username-localization/issues/3#issuecomment-326713125, or mute the thread https://github.com/notifications/unsubscribe-auth/AAV8xgTGc2TIyotFAOSr4kr-xVhd26w8ks5seK5tgaJpZM4MU4Z_ .

Artoria2e5 commented 6 years ago

干脆把 cjk 变成 ruby 的所有 letter/word posix class 吧。js 很快也要有 Unicode 属性了就是。

zh99998 commented 6 years ago

设计上只想放行 cjk 字符,而不是所有文字。因为一些西欧字符有那个奇怪的 unicode 仿冒漏洞 (具体我也不知道是啥,就是能造出来一些看起来一模一样的字符)。这是 discourse 官方不支持 unicode 用户名的原因。 而单放行 cjk 似乎就没这问题。

Artoria2e5 commented 6 years ago

可以做 LCG 三者互斥呀… 像现在域名要求一样。

并且基里尔一点都不西欧好吗!

erickguan commented 6 years ago

CJK 有这个问题,只是很少人知道怎么去伪造吧