2 # iExploder - Generates bad HTML files to perform QA for web browsers.
3 # Developed for the Mozilla Foundation.
6 # Copyright (c) 2005 Thomas Stromberg <thomas%stromberg.org>
8 # This software is provided 'as-is', without any express or implied warranty.
9 # In no event will the authors be held liable for any damages arising from the
10 # use of this software.
12 # Permission is granted to anyone to use this software for any purpose,
13 # including commercial applications, and to alter it and redistribute it
14 # freely, subject to the following restrictions:
16 # 1. The origin of this software must not be misrepresented; you must not
17 # claim that you wrote the original software. If you use this software in a
18 # product, an acknowledgment in the product documentation would be appreciated
19 # but is not required.
21 # 2. Altered source versions must be plainly marked as such, and must not be
22 # misrepresented as being the original software.
24 # 3. This notice may not be removed or altered from any source distribution.
26 # 4. Any bug reports, patches, or other publications which are based on the
27 # usage of iExploder must reference iExploder as the source of the discovery.
39 def readTagFile(filename)
41 File.new(filename).readlines.each { |line|
44 # Don't include comments.
45 if (line !~ /^# /) && (line.length > 0)
52 # based on make_up_value, essentially.
56 when 1..3 then return ($htmlValues[rand($htmlValues.length)])
57 when 4..5 then return ($htmlValues[rand($htmlValues.length)] + inventValue())
58 when 6 then return ($htmlValues[rand($htmlValues.length)] + "//" + inventValue())
60 when 8..10 then return rand(255).chr * (rand(256)+8)
61 when 11 then return rand(255).chr * (rand(2048)+8)
62 when 12 then return "#" + rand(999999).to_s
63 when 13 then return rand(999999).to_s + "%"
64 when 14..15 then return "&" + rand(999999).to_s + ";"
67 return inventValue() + "=" + inventValue()
69 when 17 then return inventValue() + "," + inventValue()
72 return "-" + rand(999999).to_s
74 return rand(999999).to_s
79 # based on make_up_value, essentially.
80 def inventCssValue(tag)
83 when 1..10 then return $cssValues[rand($cssValues.length)]
84 when 11 then return ''
85 when 12 then return rand(255).chr * (rand(8192)+8)
87 length = rand(1024) + 8
88 return (rand(255).chr * length) + " " + (rand(255).chr * length) + " " + (rand(255).chr * length)
89 when 14 then return (rand(255).chr * (rand(1024)+3)) + "px"
90 when 15 then return (rand(255).chr * (rand(1024)+3)) + "em"
91 when 16 then return "url(" + inventValue() + ")"
92 when 17..18 then return "#" + rand(999999999).to_s
93 when 19 then return "-" + rand(99999999).to_s
94 else return rand(99999999).to_s;
100 $mangledTagTotal += 1
103 # 20% chance of closing a tag instead of opening it.
105 out = "</" + tag + ">"
112 # forgot the space between the tag and the attributes
117 attrNum = rand($maxAttrs) + 1
120 attr = $htmlAttr[rand($htmlAttr.length)]
124 # 7.5% of the time we skip the = sign. Don't prefix it
125 # if the attribute ends with a ( however.
132 # sometimes quote it, sometimes not. I doubt the importance
133 # of this test, but mangleme-1.2 added it, and adding more
134 # random-ness never hurt anything but time. I'll do it less often.
143 # end the quote when you are done
148 # 5% chance we skip the space at the end of the name
158 1.upto(rand($maxCSS)+1) {
159 out << $cssTags[rand($cssTags.length)]
161 # very small chance we let the tag run on.
166 out << inventCssValue(tag)
167 # we almost always put the ; there.
175 # support our local troops!
176 if ($paramSubTestNum > 0) && ($paramSubTestNum != $mangledTagTotal)
177 if tag =~ /html|body|head/
178 return '<' + tag + '>'
180 return '<subtest-ignored>'
187 # These if statements are so that mod_ruby doesn't have to reload the files
191 $cssTags = readTagFile('cssproperties.in');
195 $htmlTags = readTagFile('htmltags.in');
198 $htmlAttr = readTagFile('htmlattrs.in');
202 $htmlValues = readTagFile('htmlvalues.in');
206 $cssValues = readTagFile('cssvalues.in');
209 ### THE INTERACTION ##################################
210 cgi = CGI.new("html4");
212 $paramTestNum = cgi.params['test'][0].to_i
213 $paramRandomMode = cgi.params['random'][0]
214 $paramLookupMode = cgi.params['lookup'][0]
215 $paramSubTestNum = cgi.params['subtest'][0].to_i || 0
224 if $paramSubTestNum > $maxTags
228 maxTags=$paramSubTestNum
235 nextTest = rand(99999999)
238 nextTest = $paramTestNum + 1
248 bodyText = mangleTag('html')
249 bodyText << "\n<head>\n"
251 # Only do redirects if lookup=1 has not been specified.
252 if (! $paramLookupMode) && ($paramSubTestNum != $maxTags)
253 newpage = "iexploder.cgi?"
254 if $paramSubTestNum > 0
255 newpage << "test=" << $paramTestNum.to_s << "&subtest=" << ($paramSubTestNum + 1).to_s
257 newpage << "test=" << nextTest.to_s
261 newpage << "&random=1"
265 bodyText << "\t<META HTTP-EQUIV=\"Refresh\" content=\"0;URL=#{newpage}\">\n"
266 # use both techniques, because you never know how you might be corrupting yourself.
267 bodyText << "\t<script language=\"javascript\">setTimeout('window.location=\"#{newpage}\"', 1000);</script>\n"
270 # If they have no test number, don't crash them, just redirect them to the next test.
273 cgi.html { bodyText }
278 bodyText << "\t" << mangleTag('meta')
279 bodyText << "\t" << mangleTag('meta')
280 bodyText << "\t" << mangleTag('link')
282 bodyText << "\t<title>(#{cgi['test']}) iExploder #{$VERSION} - #{inventValue()}</title>\n"
283 bodyText << "</head>\n\n"
285 # What tags will we be messing with ######################
288 1.upto($maxTags) { tagList << $htmlTags[rand($htmlTags.length)] }
292 bodyText << mangleTag(tag)
293 bodyText << inventValue() + "\n"
295 bodyText << "</body>\n</html>"
297 cgi.out('type' => 'text/html') do