--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKitTools/iExploder/htdocs/iexploder.rb Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,337 @@
+# iExploder - Generates bad HTML files to perform QA for web browsers.
+# Developed for the Mozilla Foundation.
+#####################
+#
+# Copyright (c) 2006 Thomas Stromberg <thomas%stromberg.org>
+#
+# This software is provided 'as-is', without any express or implied warranty.
+# In no event will the authors be held liable for any damages arising from the
+# use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software in a
+# product, an acknowledgment in the product documentation would be appreciated
+# but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source distribution.
+
+$VERSION="1.3.2"
+
+class IExploder
+ attr_accessor :test_num, :subtest_num, :lookup_mode, :random_mode, :url
+ attr_accessor :offset, :lines, :stop_num
+
+ def initialize(max_tags, max_attrs, max_props)
+ @htmlMaxTags = max_tags
+ @htmlMaxAttrs = max_attrs
+ @cssMaxProps = max_props
+ @mangledTagTotal = 0
+ @stop_num = 0
+ end
+
+ def setRandomSeed
+ if @test_num > 0
+ srand(@test_num)
+ else
+ srand
+ end
+ end
+
+
+ def readTagFiles
+ # These if statements are so that mod_ruby doesn't have to reload the files
+ # each time
+
+ if (! @cssTags)
+ @cssTags = readTagFile('cssproperties.in');
+ end
+
+ if (! @htmlTags)
+ @htmlTags = readTagFile('htmltags.in');
+ end
+ if (! @htmlAttr)
+ @htmlAttr = readTagFile('htmlattrs.in');
+ end
+
+ if (! @htmlValues)
+ @htmlValues = readTagFile('htmlvalues.in');
+ end
+
+ if (! @cssValues)
+ @cssValues = readTagFile('cssvalues.in');
+ end
+
+ end
+
+
+ def readTagFile(filename)
+ list = Array.new
+ File.new(filename).readlines.each { |line|
+ line.chop!
+
+ # Don't include comments.
+ if (line !~ /^# /) && (line.length > 0)
+ list << line
+ end
+ }
+ return list
+ end
+
+ # based on make_up_value, essentially.
+ def inventValue
+ value = rand(19);
+ case value
+ when 1..3 then return (@htmlValues[rand(@htmlValues.length)])
+ when 4..5 then return (@htmlValues[rand(@htmlValues.length)] + inventValue())
+ when 6 then return (@htmlValues[rand(@htmlValues.length)] + "//" + inventValue())
+ when 7 then return ''
+ # this may return negative argument?
+ when 8..10 then return rand(255).chr * (rand(256)+8)
+ when 11 then return rand(255).chr * (rand(2048)+8)
+ when 12 then return "#" + rand(999999).to_s
+ when 13 then return rand(999999).to_s + "%"
+ when 14..15 then return "&" + rand(999999).to_s + ";"
+ # filters
+ when 16 then
+ return inventValue() + "=" + inventValue()
+
+ # this my return undefined method + for nil:NilClass
+ when 17 then return inventValue() + "," + inventValue()
+ else
+ if rand(5) > 3
+ return "-" + rand(999999).to_s
+ else
+ return rand(999999).to_s
+ end
+ end
+ end
+
+ # based on make_up_value, essentially.
+ def inventCssValue(tag)
+ value = rand(23);
+ case value
+ when 1..10 then return @cssValues[rand(@cssValues.length)]
+ when 11 then return ''
+ when 12 then return rand(255).chr * (rand(8192)+8)
+ when 13
+ length = rand(1024) + 8
+ return (rand(255).chr * length) + " " + (rand(255).chr * length) + " " + (rand(255).chr * length)
+ when 14 then return (rand(255).chr * (rand(1024)+3)) + "px"
+ when 15 then return (rand(255).chr * (rand(1024)+3)) + "em"
+ when 16 then return "url(" + inventValue() + ")"
+ when 17..18 then return "#" + rand(999999999).to_s
+ when 19 then return "-" + rand(99999999).to_s
+ else return rand(99999999).to_s;
+ end
+ end
+
+
+ def mangleTag(tag)
+ @mangledTagTotal += 1
+ out = ''
+
+ # 20% chance of closing a tag instead of opening it. This
+ # still counts against @mangledTagTotal, however.
+ if rand(10) > 8
+ out = "</" + tag + ">"
+ return out
+ end
+
+ # we're opening it.
+ out = "<" + tag
+
+ # forgot the space between the tag and the attributes
+ if rand(15) > 1
+ out << ' '
+ end
+
+ attrNum = rand(@htmlMaxAttrs) + 1
+
+ 1.upto(attrNum) {
+ attr = @htmlAttr[rand(@htmlAttr.length)]
+
+ out << attr
+
+ # 7.5% of the time we skip the = sign. Don't prefix it
+ # if the attribute ends with a ( however.
+
+
+ if rand(15) > 1
+ out << '='
+ end
+
+ # sometimes quote it, sometimes not. I doubt the importance
+ # of this test, but mangleme-1.2 added it, and adding more
+ # random-ness never hurt anything but time. I'll do it less often.
+ quote = rand(2)
+ if (quote > 1)
+ out << "\""
+ end
+
+ out << inventValue()
+
+ # end the quote when you are done
+ if (quote > 1)
+ out << "\" "
+ end
+
+ # 5% chance we skip the space at the end of the name
+ if rand(20) > 1
+ out << ' '
+ end
+
+ }
+
+ # CSS styles!
+ if rand(4) > 1
+ out << " style=\""
+ 1.upto(rand(@cssMaxProps)+1) {
+ out << @cssTags[rand(@cssTags.length)]
+
+ # very small chance we let the tag run on.
+ if rand(50) > 1
+ out << ": "
+ end
+
+ out << inventCssValue(tag)
+ # we almost always put the ; there.
+ if rand(50) > 1
+ out << '; '
+ end
+ }
+ out << "\""
+ end
+
+ out << ">\n"
+
+ # support our local troops!
+ if (@subtest_num > 0) && filterSubTest()
+ if tag =~ /html|body|head/
+ return '<' + tag + '>'
+ else
+ return "<x-#@mangledTagTotal>\n"
+ end
+ else
+ return out
+ end
+ end
+ #end
+
+ def filterSubTest()
+ result = 1
+ if (@mangledTagTotal >= @offset) && (@mangledTagTotal < (@offset + @lines))
+ result = nil
+ end
+ return result
+ end
+
+ def nextTestNum()
+ if random_mode
+ n = rand(99999999)
+ else
+ if @test_num
+ n = @test_num + 1
+ else
+ n = 1
+ end
+ end
+ return n
+ end
+
+ # If we are at line 30 with 8 extra lines, there is no point to try line 31
+ # with 8 lines as well.. skip back to 1 and bump up the line count.
+ def nextSubTestNum()
+ if (@offset + @lines) > @htmlMaxTags
+ nextNum = ((@lines * 2 -1)) * @htmlMaxTags
+ else
+ nextNum = @subtest_num + 1
+ end
+ return nextNum
+ end
+
+
+ def buildPage
+ if (! @test_num) || (@test_num < 1)
+ @test_num = 1
+ end
+ next_num=nextTestNum()
+ @lines = @subtest_num.div(@htmlMaxTags) + 1
+ @offset = @subtest_num.modulo(@htmlMaxTags)
+
+ # building the HTML
+ bodyText = mangleTag('html')
+ bodyText << "\n<head>\n"
+
+ # Only do redirects if lookup=1 has not been specified.
+ if (! @lookup_mode) && (@lines <= @htmlMaxTags) && (@stop_num != @test_num)
+ newpage = @url + "?"
+ if @subtest_num > 0
+ newpage << "test=" << @test_num.to_s << "&subtest=" << nextSubTestNum().to_s
+ else
+ newpage << "test=" << next_num.to_s
+ end
+
+ if @random_mode
+ newpage << "&random=1"
+ end
+
+ if @stop_num > 0
+ newpage << "&stop=" << @stop_num.to_s
+ end
+
+ bodyText << "\t<META HTTP-EQUIV=\"Refresh\" content=\"0;URL=#{newpage}\">\n"
+ # use both techniques, because you never know how you might be corrupting yourself.
+ bodyText << "\t<script language=\"javascript\">setTimeout('window.location=\"#{newpage}\"', 1000);</script>\n"
+ end
+
+ bodyText << "\t" << mangleTag('meta')
+ bodyText << "\t" << mangleTag('meta')
+ bodyText << "\t" << mangleTag('link')
+
+ bodyText << "\t<title>[#@test_num] iExploder #{$VERSION} - #{inventValue()}</title>\n"
+ bodyText << "</head>\n\n"
+
+ # What tags will we be messing with ######################
+ tagList = [ 'body']
+
+ # we already have 5 tags?
+ 1.upto(@htmlMaxTags - 5 ) { tagList << @htmlTags[rand(@htmlTags.length)] }
+
+ tagList.each { |tag|
+ bodyText << mangleTag(tag)
+ bodyText << inventValue() + "\n"
+ }
+ bodyText << "</body>\n</html>"
+ end
+end
+
+
+
+if $0 == __FILE__
+ max=ARGV[0].to_i
+ puts "testing #{max} tags"
+ test = IExploder.new(max, 5, 5)
+ test.readTagFiles()
+ test.test_num=1
+ test.subtest_num=1
+ counter=0
+ test.lines=0
+
+ while test.lines < max
+ test.lines = test.subtest_num.div(max) + 1
+ test.offset = test.subtest_num.modulo(max)
+ test.subtest_num=test.nextSubTestNum
+ counter = counter + 1
+ puts "[#{counter}] subtest #{test.subtest_num} is #{test.lines} lines with #{test.offset} offset"
+ end
+
+ puts "for #{max} tests, you will have #{counter} iterations until #{test.subtest_num}"
+end
+