webengine/osswebengine/WebKitTools/iExploder/htdocs/iexploder.rb
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 # iExploder - Generates bad HTML files to perform QA for web browsers.
       
     2 # Developed for the Mozilla Foundation.
       
     3 #####################
       
     4 #
       
     5 # Copyright (c) 2006 Thomas Stromberg <thomas%stromberg.org>
       
     6 # 
       
     7 # This software is provided 'as-is', without any express or implied warranty.
       
     8 # In no event will the authors be held liable for any damages arising from the
       
     9 # use of this software.
       
    10 # 
       
    11 # Permission is granted to anyone to use this software for any purpose,
       
    12 # including commercial applications, and to alter it and redistribute it
       
    13 # freely, subject to the following restrictions:
       
    14 # 
       
    15 # 1. The origin of this software must not be misrepresented; you must not
       
    16 # claim that you wrote the original software. If you use this software in a
       
    17 # product, an acknowledgment in the product documentation would be appreciated
       
    18 # but is not required.
       
    19 # 
       
    20 # 2. Altered source versions must be plainly marked as such, and must not be
       
    21 # misrepresented as being the original software.
       
    22 # 
       
    23 # 3. This notice may not be removed or altered from any source distribution.
       
    24 
       
    25 $VERSION="1.3.2"
       
    26 
       
    27 class IExploder
       
    28     attr_accessor :test_num, :subtest_num, :lookup_mode, :random_mode, :url
       
    29     attr_accessor :offset, :lines, :stop_num
       
    30     
       
    31     def initialize(max_tags, max_attrs, max_props)
       
    32         @htmlMaxTags = max_tags
       
    33         @htmlMaxAttrs = max_attrs
       
    34         @cssMaxProps = max_props
       
    35         @mangledTagTotal = 0
       
    36         @stop_num = 0
       
    37     end
       
    38     
       
    39     def setRandomSeed
       
    40         if @test_num > 0
       
    41             srand(@test_num)
       
    42         else
       
    43             srand
       
    44         end
       
    45     end
       
    46     
       
    47     
       
    48     def readTagFiles
       
    49         # These if statements are so that mod_ruby doesn't have to reload the files
       
    50         # each time
       
    51         
       
    52         if (! @cssTags)
       
    53             @cssTags = readTagFile('cssproperties.in');
       
    54         end
       
    55         
       
    56         if (! @htmlTags)
       
    57             @htmlTags = readTagFile('htmltags.in');
       
    58         end
       
    59         if (! @htmlAttr)
       
    60             @htmlAttr = readTagFile('htmlattrs.in');
       
    61         end
       
    62         
       
    63         if (! @htmlValues)
       
    64             @htmlValues = readTagFile('htmlvalues.in');
       
    65         end
       
    66         
       
    67         if (! @cssValues)
       
    68             @cssValues = readTagFile('cssvalues.in');
       
    69         end
       
    70         
       
    71     end
       
    72     
       
    73     
       
    74     def readTagFile(filename)
       
    75         list = Array.new
       
    76         File.new(filename).readlines.each { |line|
       
    77             line.chop!
       
    78             
       
    79             # Don't include comments.
       
    80             if (line !~ /^# /) && (line.length > 0)
       
    81                 list << line
       
    82             end
       
    83         }
       
    84         return  list
       
    85     end
       
    86     
       
    87     # based on make_up_value, essentially.
       
    88     def inventValue
       
    89         value = rand(19);
       
    90         case value
       
    91         when 1..3 then return (@htmlValues[rand(@htmlValues.length)])
       
    92         when 4..5 then return (@htmlValues[rand(@htmlValues.length)] + inventValue())
       
    93         when 6 then return (@htmlValues[rand(@htmlValues.length)] + "//" + inventValue())
       
    94         when 7 then return ''
       
    95             # this may return negative argument?
       
    96         when 8..10 then return rand(255).chr * (rand(256)+8)
       
    97         when 11 then return rand(255).chr * (rand(2048)+8)
       
    98         when 12 then return "#" + rand(999999).to_s
       
    99         when 13 then return rand(999999).to_s + "%"
       
   100         when 14..15 then return "&" + rand(999999).to_s + ";"
       
   101             # filters
       
   102         when 16 then
       
   103             return inventValue() + "=" + inventValue()
       
   104             
       
   105             # this my return undefined method + for nil:NilClass
       
   106         when 17 then return inventValue() + "," + inventValue()
       
   107         else
       
   108             if rand(5) > 3
       
   109                 return "-" + rand(999999).to_s
       
   110             else
       
   111                 return rand(999999).to_s
       
   112             end
       
   113         end
       
   114     end
       
   115     
       
   116     # based on make_up_value, essentially.
       
   117     def inventCssValue(tag)
       
   118         value = rand(23);
       
   119         case value
       
   120         when 1..10 then return @cssValues[rand(@cssValues.length)]
       
   121         when 11 then return ''
       
   122         when 12 then return rand(255).chr * (rand(8192)+8)
       
   123         when 13
       
   124             length = rand(1024) + 8
       
   125             return (rand(255).chr * length) + " " + (rand(255).chr * length) + " " + (rand(255).chr * length)
       
   126         when 14 then return (rand(255).chr * (rand(1024)+3)) + "px"
       
   127         when 15 then return (rand(255).chr * (rand(1024)+3)) + "em"
       
   128         when 16 then return "url(" + inventValue() + ")"
       
   129         when 17..18 then return "#" + rand(999999999).to_s
       
   130         when 19 then return "-" + rand(99999999).to_s
       
   131         else return rand(99999999).to_s;
       
   132         end
       
   133     end
       
   134     
       
   135     
       
   136     def mangleTag(tag)
       
   137         @mangledTagTotal += 1
       
   138         out = ''
       
   139         
       
   140         # 20% chance of closing a tag instead of opening it. This 
       
   141         # still counts against @mangledTagTotal, however.
       
   142         if rand(10) > 8
       
   143             out = "</" + tag + ">"
       
   144             return out
       
   145         end
       
   146         
       
   147         # we're opening it.
       
   148         out = "<" + tag
       
   149         
       
   150         # forgot the space between the tag and the attributes
       
   151         if rand(15) > 1
       
   152             out << ' '
       
   153         end
       
   154         
       
   155         attrNum = rand(@htmlMaxAttrs) + 1
       
   156         
       
   157         1.upto(attrNum) {
       
   158             attr = @htmlAttr[rand(@htmlAttr.length)]
       
   159             
       
   160             out << attr
       
   161             
       
   162             # 7.5% of the time we skip the = sign. Don't prefix it
       
   163             # if the attribute ends with a ( however.
       
   164             
       
   165             
       
   166             if rand(15) > 1
       
   167                 out << '='
       
   168             end
       
   169             
       
   170             # sometimes quote it, sometimes not. I doubt the importance
       
   171             # of this test, but mangleme-1.2 added it, and adding more
       
   172             # random-ness never hurt anything but time. I'll do it less often.
       
   173             quote = rand(2)
       
   174             if (quote > 1)
       
   175                 out << "\""
       
   176             end
       
   177             
       
   178             out << inventValue()
       
   179             
       
   180             # end the quote when you are done
       
   181             if (quote > 1)
       
   182                 out << "\" "
       
   183             end
       
   184             
       
   185             # 5% chance we skip the space at the end of the name
       
   186             if rand(20) > 1
       
   187                 out << ' '
       
   188             end
       
   189             
       
   190         }
       
   191         
       
   192         # CSS styles!
       
   193         if rand(4) > 1
       
   194             out << " style=\""
       
   195             1.upto(rand(@cssMaxProps)+1) {
       
   196                 out << @cssTags[rand(@cssTags.length)]
       
   197                 
       
   198                 # very small chance we let the tag run on.
       
   199                 if rand(50) > 1
       
   200                     out << ": "
       
   201                 end
       
   202                 
       
   203                 out << inventCssValue(tag)
       
   204                 # we almost always put the ; there.
       
   205                 if rand(50) > 1
       
   206                     out << '; '
       
   207                 end
       
   208             }
       
   209             out << "\""
       
   210         end
       
   211         
       
   212         out << ">\n"
       
   213         
       
   214         # support our local troops!
       
   215         if (@subtest_num > 0) && filterSubTest() 
       
   216             if tag =~ /html|body|head/
       
   217                 return '<' + tag + '>'
       
   218             else
       
   219                 return "<x-#@mangledTagTotal>\n"
       
   220             end
       
   221         else
       
   222             return out
       
   223         end    
       
   224     end
       
   225     #end
       
   226     
       
   227     def filterSubTest()
       
   228         result = 1
       
   229         if (@mangledTagTotal >= @offset) && (@mangledTagTotal < (@offset + @lines))
       
   230             result = nil
       
   231         end
       
   232         return result
       
   233     end
       
   234     
       
   235     def nextTestNum()
       
   236         if random_mode
       
   237             n = rand(99999999)
       
   238         else
       
   239             if @test_num
       
   240                 n = @test_num  + 1
       
   241             else
       
   242                 n = 1
       
   243             end
       
   244         end
       
   245         return n
       
   246     end
       
   247     
       
   248     # If we are at line 30 with 8 extra lines, there is no point to try line 31
       
   249     # with 8 lines as well.. skip back to 1 and bump up the line count.
       
   250     def nextSubTestNum()    
       
   251         if (@offset + @lines) > @htmlMaxTags
       
   252             nextNum = ((@lines * 2 -1)) * @htmlMaxTags
       
   253         else
       
   254             nextNum = @subtest_num + 1
       
   255         end      
       
   256         return nextNum
       
   257     end
       
   258     
       
   259     
       
   260     def buildPage
       
   261         if (! @test_num) || (@test_num < 1)
       
   262             @test_num = 1
       
   263         end
       
   264         next_num=nextTestNum()
       
   265         @lines = @subtest_num.div(@htmlMaxTags) + 1
       
   266         @offset = @subtest_num.modulo(@htmlMaxTags)
       
   267         
       
   268         # building the HTML
       
   269         bodyText = mangleTag('html')
       
   270         bodyText << "\n<head>\n"
       
   271         
       
   272         # Only do redirects if lookup=1 has not been specified.
       
   273         if (! @lookup_mode) && (@lines <= @htmlMaxTags) && (@stop_num != @test_num)
       
   274             newpage = @url + "?"
       
   275             if @subtest_num > 0
       
   276                 newpage << "test=" << @test_num.to_s << "&subtest=" << nextSubTestNum().to_s
       
   277             else
       
   278                 newpage << "test=" << next_num.to_s
       
   279             end
       
   280             
       
   281             if @random_mode
       
   282                 newpage << "&random=1"
       
   283             end
       
   284             
       
   285             if @stop_num > 0
       
   286                 newpage << "&stop=" << @stop_num.to_s
       
   287             end
       
   288             
       
   289             bodyText << "\t<META HTTP-EQUIV=\"Refresh\" content=\"0;URL=#{newpage}\">\n" 
       
   290             # use both techniques, because you never know how you might be corrupting yourself.
       
   291             bodyText << "\t<script language=\"javascript\">setTimeout('window.location=\"#{newpage}\"', 1000);</script>\n" 
       
   292         end
       
   293         
       
   294         bodyText << "\t" << mangleTag('meta')
       
   295         bodyText << "\t" <<  mangleTag('meta')
       
   296         bodyText << "\t" <<  mangleTag('link')
       
   297         
       
   298         bodyText << "\t<title>[#@test_num] iExploder #{$VERSION} - #{inventValue()}</title>\n"
       
   299         bodyText << "</head>\n\n"
       
   300         
       
   301         # What tags will we be messing with ######################
       
   302         tagList = [ 'body']
       
   303         
       
   304         # we already have 5 tags?
       
   305         1.upto(@htmlMaxTags - 5 ) { tagList << @htmlTags[rand(@htmlTags.length)] }
       
   306         
       
   307         tagList.each { |tag|
       
   308             bodyText << mangleTag(tag)
       
   309             bodyText << inventValue() + "\n"
       
   310         }
       
   311         bodyText << "</body>\n</html>"
       
   312     end
       
   313 end
       
   314 
       
   315 
       
   316 
       
   317 if $0 == __FILE__
       
   318     max=ARGV[0].to_i
       
   319     puts "testing #{max} tags"
       
   320     test = IExploder.new(max, 5, 5)
       
   321     test.readTagFiles()
       
   322     test.test_num=1
       
   323     test.subtest_num=1
       
   324     counter=0
       
   325     test.lines=0
       
   326 
       
   327     while test.lines < max
       
   328         test.lines = test.subtest_num.div(max) + 1
       
   329         test.offset = test.subtest_num.modulo(max)
       
   330         test.subtest_num=test.nextSubTestNum
       
   331         counter = counter + 1
       
   332 	puts "[#{counter}] subtest #{test.subtest_num} is #{test.lines} lines with #{test.offset} offset"
       
   333     end
       
   334 
       
   335     puts "for #{max} tests, you will have #{counter} iterations until #{test.subtest_num}"
       
   336 end
       
   337