UserUpdater 类中的不一致行为

@eviltrout

复现步骤:

  1. 创建一个用户字段,其 ID 为 1
  2. 将下方代码的第二行运行两次。

情况 1

up = UserUpdater.new(Discourse.system_user, User.find(1))
up.update({:custom_fields=>{:user_field_1=>"abc"}})
  1. 访问 /my/preferences/profile 时,你会看到 abc 出现了两次。

令人惊讶的是,通过 /my/preferences/profile 更新个人资料时,一切正常。

情况 2

这种情况似乎工作正常

up = UserUpdater.new(Discourse.system_user, User.find(1))
params = ActionController::Parameters.new({:custom_fields=>{:user_field_1=>"abc"}})
up.update(params.permit!)

在情况 1 中,值被推入数组,并在 /my/preferences/profile 上以逗号分隔的值显示。

情况 2 似乎执行了正确的操作,即用新值替换当前值,但将其包裹在 ActionController::Parameters 中显得不自然。

4 个赞

这确实看起来是一个有效的漏洞,应该予以修复,感谢您的报告!

4 个赞

我的分析结论如下。

# 情况 1
u1 = User.find(1)
u1.custom_fields[:user_field_1] = "abc"
u1.save

# 情况 2
u1.custom_fields["user_field_1"] = "abc"
u1.save

在情况 1 中,每次调用 u1.save 都会创建一条新的 UserCustomField 记录。

在情况 2 中,数据库中所有名称为 user_field_1UserCustomField 记录都会被删除,除了指定的那一条。
Screenshot 2020-08-20 at 11.56.49 AM

总而言之,在 HasCustomFields 混入模块中,同一键的 symbol 版本和 string 版本被区别对待。

1 个赞

好的,我动手了。这是修复该问题的 PR:

7 个赞

好的,这个已经合并了。

3 个赞