diff --git a/plugins/poll/assets/javascripts/poll_dialect.js b/plugins/poll/assets/javascripts/poll_dialect.js index 405b8ee85fe..70771e41568 100644 --- a/plugins/poll/assets/javascripts/poll_dialect.js +++ b/plugins/poll/assets/javascripts/poll_dialect.js @@ -57,7 +57,7 @@ if (attributes[DATA_PREFIX + "type"] === "number") { // default values if (isNaN(min)) { min = 1; } - if (isNaN(max)) { max = 10; } + if (isNaN(max)) { max = Discourse.SiteSettings.poll_maximum_options; } if (isNaN(step)) { step = 1; } // dynamically generate options contents.push(["bulletlist"]); diff --git a/plugins/poll/config/locales/client.en.yml b/plugins/poll/config/locales/client.en.yml index 0096484b731..ffafed3c9e1 100644 --- a/plugins/poll/config/locales/client.en.yml +++ b/plugins/poll/config/locales/client.en.yml @@ -21,9 +21,9 @@ en: multiple: help: - at_least_min_options: "You may choose at least <strong>%{count}</strong> options." + at_least_min_options: "You must choose at least <strong>%{count}</strong> options." up_to_max_options: "You may choose up to <strong>%{count}</strong> options." - x_options: "You may choose <strong>%{count}</strong> options." + x_options: "You must choose <strong>%{count}</strong> options." between_min_and_max_options: "You may choose between <strong>%{min}</strong> and <strong>%{max}</strong> options." cast-votes: diff --git a/plugins/poll/config/locales/server.en.yml b/plugins/poll/config/locales/server.en.yml index b1d5582c255..236103501af 100644 --- a/plugins/poll/config/locales/server.en.yml +++ b/plugins/poll/config/locales/server.en.yml @@ -23,6 +23,9 @@ en: default_poll_must_have_different_options: "Poll must have different options." named_poll_must_have_different_options: "Poll named <strong>%{name}</strong> must have different options." + default_poll_with_multiple_choices_has_invalid_parameters: "Poll with multiple choices has invalid parameters." + named_poll_with_multiple_choices_has_invalid_parameters: "Poll named <strong>%{name}</strong> with multiple choice has invalid parameters." + requires_at_least_1_valid_option: "You must select at least 1 valid option." cannot_change_polls_after_5_minutes: "You cannot add, remove or rename polls after the first 5 minutes." diff --git a/plugins/poll/plugin.rb b/plugins/poll/plugin.rb index ead1b6122d3..056001f8a29 100644 --- a/plugins/poll/plugin.rb +++ b/plugins/poll/plugin.rb @@ -248,6 +248,19 @@ after_initialize do return end + # poll with multiple choices + if poll["type"] == "multiple" + min = (poll["min"].presence || 1).to_i + max = (poll["max"].presence || poll["options"].size).to_i + + if min > max || max <= 0 || max > poll["options"].size || min >= poll["options"].size + poll["name"] == DEFAULT_POLL_NAME ? + self.errors.add(:base, I18n.t("poll.default_poll_with_multiple_choices_has_invalid_parameters")) : + self.errors.add(:base, I18n.t("poll.named_poll_with_multiple_choices_has_invalid_parameters", name: poll["name"])) + return + end + end + # store the valid poll polls[poll["name"]] = poll end diff --git a/plugins/poll/spec/controllers/posts_controller_spec.rb b/plugins/poll/spec/controllers/posts_controller_spec.rb index f0f128f3a36..dd4699345cb 100644 --- a/plugins/poll/spec/controllers/posts_controller_spec.rb +++ b/plugins/poll/spec/controllers/posts_controller_spec.rb @@ -49,6 +49,13 @@ describe PostsController do expect(json["errors"][0]).to eq(I18n.t("poll.default_poll_must_have_less_options", max: SiteSetting.poll_maximum_options)) end + it "should have valid parameters" do + xhr :post, :create, { title: title, raw: "[poll type=multiple min=5]\n- A\n- B[/poll]" } + expect(response).not_to be_success + json = ::JSON.parse(response.body) + expect(json["errors"][0]).to eq(I18n.t("poll.default_poll_with_multiple_choices_has_invalid_parameters")) + end + it "prevents self-xss" do xhr :post, :create, { title: title, raw: "[poll name=<script>alert('xss')</script>]\n- A\n- B\n[/poll]" } expect(response).to be_success