summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorFlorian Frank <flori@ping.de>2009-08-24 16:20:32 +0200
committerFlorian Frank <flori@ping.de>2009-08-24 16:20:32 +0200
commit10f03df1f6a54edaae86e87e1fd7d9a6a6a319f1 (patch)
treed7133d6f5ba8bc2f195ee6e070b34331bd4f5d04 /tools
downloadjson-10f03df1f6a54edaae86e87e1fd7d9a6a6a319f1.tar.gz
initial commit
Diffstat (limited to 'tools')
-rwxr-xr-xtools/fuzz.rb139
-rwxr-xr-xtools/server.rb61
2 files changed, 200 insertions, 0 deletions
diff --git a/tools/fuzz.rb b/tools/fuzz.rb
new file mode 100755
index 0000000..4dacd95
--- /dev/null
+++ b/tools/fuzz.rb
@@ -0,0 +1,139 @@
+require 'json'
+
+require 'iconv'
+ISO_8859_1_TO_UTF8 = Iconv.new('utf-8', 'iso-8859-15')
+class ::String
+ def to_utf8
+ ISO_8859_1_TO_UTF8.iconv self
+ end
+end
+
+class Fuzzer
+ def initialize(n, freqs = {})
+ sum = freqs.inject(0.0) { |s, x| s + x.last }
+ freqs.each_key { |x| freqs[x] /= sum }
+ s = 0.0
+ freqs.each_key do |x|
+ freqs[x] = s .. (s + t = freqs[x])
+ s += t
+ end
+ @freqs = freqs
+ @n = n
+ @alpha = (0..0xff).to_a
+ end
+
+ def random_string
+ s = ''
+ 30.times { s << @alpha[rand(@alpha.size)] }
+ s.to_utf8
+ end
+
+ def pick
+ r = rand
+ found = @freqs.find { |k, f| f.include? rand }
+ found && found.first
+ end
+
+ def make_pick
+ k = pick
+ case
+ when k == Hash, k == Array
+ k.new
+ when k == true, k == false, k == nil
+ k
+ when k == String
+ random_string
+ when k == Fixnum
+ rand(2 ** 30) - 2 ** 29
+ when k == Bignum
+ rand(2 ** 70) - 2 ** 69
+ end
+ end
+
+ def fuzz(current = nil)
+ if @n > 0
+ case current
+ when nil
+ @n -= 1
+ current = fuzz [ Hash, Array ][rand(2)].new
+ when Array
+ while @n > 0
+ @n -= 1
+ current << case p = make_pick
+ when Array, Hash
+ fuzz(p)
+ else
+ p
+ end
+ end
+ when Hash
+ while @n > 0
+ @n -= 1
+ current[random_string] = case p = make_pick
+ when Array, Hash
+ fuzz(p)
+ else
+ p
+ end
+ end
+ end
+ end
+ current
+ end
+end
+
+class MyState < JSON.state
+ WS = " \r\t\n"
+
+ def initialize
+ super(
+ :indent => make_spaces,
+ :space => make_spaces,
+ :space_before => make_spaces,
+ :object_nl => make_spaces,
+ :array_nl => make_spaces,
+ :max_nesting => false
+ )
+ end
+
+ def make_spaces
+ s = ''
+ rand(1).times { s << WS[rand(WS.size)] }
+ s
+ end
+end
+
+n = (ARGV.shift || 500).to_i
+loop do
+ fuzzer = Fuzzer.new(n,
+ Hash => 25,
+ Array => 25,
+ String => 10,
+ Fixnum => 10,
+ Bignum => 10,
+ nil => 5,
+ true => 5,
+ false => 5
+ )
+ o1 = fuzzer.fuzz
+ json = JSON.generate o1, MyState.new
+ if $DEBUG
+ puts "-" * 80
+ puts json, json.size
+ else
+ puts json.size
+ end
+ begin
+ o2 = JSON.parse(json, :max_nesting => false)
+ rescue JSON::ParserError => e
+ puts "Caught #{e.class}: #{e.message}\n#{e.backtrace * "\n"}"
+ puts "o1 = #{o1.inspect}", "json = #{json}", "json_str = #{json.inspect}"
+ puts "locals = #{local_variables.inspect}"
+ exit
+ end
+ if o1 != o2
+ puts "mismatch", "o1 = #{o1.inspect}", "o2 = #{o2.inspect}",
+ "json = #{json}", "json_str = #{json.inspect}"
+ puts "locals = #{local_variables.inspect}"
+ end
+end
diff --git a/tools/server.rb b/tools/server.rb
new file mode 100755
index 0000000..084377f
--- /dev/null
+++ b/tools/server.rb
@@ -0,0 +1,61 @@
+#!/usr/bin/env ruby
+
+require 'webrick'
+include WEBrick
+$:.unshift 'ext'
+$:.unshift 'lib'
+require 'json'
+
+class JSONServlet < HTTPServlet::AbstractServlet
+ @@count = 1
+
+ def do_GET(req, res)
+ obj = {
+ "TIME" => Time.now.strftime("%FT%T"),
+ "foo" => "Bär",
+ "bar" => "© ≠ €!",
+ 'a' => 2,
+ 'b' => 3.141,
+ 'COUNT' => @@count += 1,
+ 'c' => 'c',
+ 'd' => [ 1, "b", 3.14 ],
+ 'e' => { 'foo' => 'bar' },
+ 'g' => "松本行弘",
+ 'h' => 1000.0,
+ 'i' => 0.001,
+ 'j' => "\xf0\xa0\x80\x81",
+ }
+ res.body = JSON.generate obj
+ res['Content-Type'] = "application/json"
+ end
+end
+
+def create_server(err, dir, port)
+ dir = File.expand_path(dir)
+ err.puts "Surf to:", "http://#{Socket.gethostname}:#{port}"
+
+ s = HTTPServer.new(
+ :Port => port,
+ :DocumentRoot => dir,
+ :Logger => WEBrick::Log.new(err),
+ :AccessLog => [
+ [ err, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
+ [ err, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
+ [ err, WEBrick::AccessLog::AGENT_LOG_FORMAT ]
+ ]
+ )
+ s.mount("/json", JSONServlet)
+ s
+end
+
+default_dir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'data'))
+dir = ARGV.shift || default_dir
+port = (ARGV.shift || 6666).to_i
+s = create_server(STDERR, dir, 6666)
+t = Thread.new { s.start }
+trap(:INT) do
+ s.shutdown
+ t.join
+ exit
+end
+sleep