Skip to content

Commit 556c94d

Browse files
committed
allow more flexible widths/heights in user content
old UserContent.css_size was really weird about what it would accept and when it would return a String vs. a Float. the times it returned a Float, it would make api_user_content explode. fix that and add some specs. the vulnerable code was exercised, among other places, in the assignment json, which impacts gradebooks and other UI features. fixes #9881 test-plan: - create an assignment in a course - in the assignment description, include the html <object width='100%' /> - try and view the gradebook for the course - it should not have an ajax request error Change-Id: I02e824414013347730185fbf7f7fb94a951f3e77 Reviewed-on: https://gerrit.instructure.com/12895 Reviewed-by: Jacob Fugal <jacob@instructure.com> Tested-by: Jenkins <jenkins@instructure.com>
1 parent ffa00a2 commit 556c94d

3 files changed

Lines changed: 96 additions & 4 deletions

File tree

lib/user_content.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,23 @@ def self.find_user_content(html)
7272
end
7373
end
7474

75+
# TODO: try and discover the motivation behind the "huhs"
7576
def self.css_size(val)
76-
res = val.to_f
77-
res = nil if res == 0
78-
res = (res + 10).to_s + "px" if res && res.to_s == val
79-
res
77+
if !val || val.to_f == 0
78+
# no value, non-numeric value, or 0 value (whether "0", "0px", "0%",
79+
# etc.); ignore
80+
nil
81+
elsif val == "#{val.to_f.to_s}%" || val == "#{val.to_f.to_s}px"
82+
# numeric percentage or specific px value; use as is
83+
val
84+
elsif val.to_f.to_s == val
85+
# unadorned numeric value; make px (after adding 10... huh?)
86+
(val.to_f + 10).to_s + "px"
87+
else
88+
# numeric value embedded, but has additional text we didn't recognize;
89+
# just extract the numeric part (without a px... huh?)
90+
val.to_f.to_s
91+
end
8092
end
8193

8294
class HtmlRewriter

spec/apis/v1/assignment_groups_api_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,4 +237,19 @@
237237

238238
json.each { |group| group['group_weight'].should be_nil }
239239
end
240+
241+
it "should not explode on assignments with <objects> with percentile widths" do
242+
course_with_teacher(:active_all => true)
243+
group = @course.assignment_groups.create!(:name => 'group')
244+
assignment = @course.assignments.create!(:title => "test", :assignment_group => group, :points_possible => 10)
245+
assignment.description = '<object width="100%" />'
246+
assignment.save!
247+
248+
api_call(:get, "/api/v1/courses/#{@course.id}/assignment_groups.json?include[]=assignments",
249+
:controller => 'assignment_groups',
250+
:action => 'index',
251+
:format => 'json',
252+
:course_id => @course.id.to_s,
253+
:include => ['assignments'])
254+
end
240255
end

spec/lib/user_content_spec.rb

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#
2+
# Copyright (C) 2011 Instructure, Inc.
3+
#
4+
# This file is part of Canvas.
5+
#
6+
# Canvas is free software: you can redistribute it and/or modify it under
7+
# the terms of the GNU Affero General Public License as published by the Free
8+
# Software Foundation, version 3 of the License.
9+
#
10+
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
11+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12+
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13+
# details.
14+
#
15+
# You should have received a copy of the GNU Affero General Public License along
16+
# with this program. If not, see <http://www.gnu.org/licenses/>.
17+
#
18+
19+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
20+
21+
describe UserContent do
22+
describe "find_user_content" do
23+
it "should not yield non-string width/height fields" do
24+
doc = Nokogiri::HTML::DocumentFragment.parse('<object width="100%" />')
25+
UserContent.find_user_content(doc) do |node, uc|
26+
uc.width.should == '100%'
27+
end
28+
end
29+
end
30+
31+
describe "css_size" do
32+
it "should be nil for non-numbers" do
33+
UserContent.css_size(nil).should be_nil
34+
UserContent.css_size('').should be_nil
35+
UserContent.css_size('non-number').should be_nil
36+
end
37+
38+
it "should be nil for numbers that equate to 0" do
39+
UserContent.css_size('0%').should be_nil
40+
UserContent.css_size('0px').should be_nil
41+
UserContent.css_size('0').should be_nil
42+
end
43+
44+
it "should preserve percents" do
45+
UserContent.css_size('100%').should == '100%'
46+
end
47+
48+
it "should preserve px" do
49+
UserContent.css_size('100px').should == '100px'
50+
end
51+
52+
# TODO: these ones are questionable
53+
it "should add 10 to raw numbers and make them px" do
54+
UserContent.css_size('100').should == '110px'
55+
end
56+
57+
it "should be nil for numbers with an unrecognized prefix" do
58+
UserContent.css_size('x-100').should be_nil
59+
end
60+
61+
it "should keep just the raw number from numbers with an unrecognized suffix" do
62+
UserContent.css_size('100-x').should == '100'
63+
end
64+
end
65+
end

0 commit comments

Comments
 (0)