miketracy-wwmd 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/History.txt +3 -0
  2. data/README +62 -0
  3. data/README.txt +62 -0
  4. data/Rakefile +34 -0
  5. data/examples/config_example.yaml +24 -0
  6. data/examples/wwmd_example.rb +73 -0
  7. data/lib/wwmd.rb +78 -0
  8. data/lib/wwmd/encoding.rb +40 -0
  9. data/lib/wwmd/form.rb +110 -0
  10. data/lib/wwmd/form_array.rb +273 -0
  11. data/lib/wwmd/guid.rb +155 -0
  12. data/lib/wwmd/hpricot_html2text.rb +76 -0
  13. data/lib/wwmd/mixins.rb +318 -0
  14. data/lib/wwmd/mixins_extends.rb +188 -0
  15. data/lib/wwmd/mixins_external.rb +18 -0
  16. data/lib/wwmd/nokogiri_html2text.rb +41 -0
  17. data/lib/wwmd/page.rb +414 -0
  18. data/lib/wwmd/page/auth.rb +183 -0
  19. data/lib/wwmd/page/config.rb +44 -0
  20. data/lib/wwmd/page/constants.rb +60 -0
  21. data/lib/wwmd/page/headers.rb +107 -0
  22. data/lib/wwmd/page/inputs.rb +47 -0
  23. data/lib/wwmd/page/irb_helpers.rb +90 -0
  24. data/lib/wwmd/page/scrape.rb +202 -0
  25. data/lib/wwmd/page/spider.rb +127 -0
  26. data/lib/wwmd/page/urlparse.rb +79 -0
  27. data/lib/wwmd/page/utils.rb +30 -0
  28. data/lib/wwmd/viewstate.rb +118 -0
  29. data/lib/wwmd/viewstate/viewstate_class_helpers.rb +35 -0
  30. data/lib/wwmd/viewstate/viewstate_deserializer_methods.rb +213 -0
  31. data/lib/wwmd/viewstate/viewstate_from_xml.rb +126 -0
  32. data/lib/wwmd/viewstate/viewstate_types.rb +51 -0
  33. data/lib/wwmd/viewstate/viewstate_utils.rb +157 -0
  34. data/lib/wwmd/viewstate/viewstate_yaml.rb +25 -0
  35. data/lib/wwmd/viewstate/vs_array.rb +36 -0
  36. data/lib/wwmd/viewstate/vs_binary_serialized.rb +28 -0
  37. data/lib/wwmd/viewstate/vs_hashtable.rb +40 -0
  38. data/lib/wwmd/viewstate/vs_hybrid_dict.rb +40 -0
  39. data/lib/wwmd/viewstate/vs_indexed_string.rb +6 -0
  40. data/lib/wwmd/viewstate/vs_indexed_string_ref.rb +22 -0
  41. data/lib/wwmd/viewstate/vs_int_enum.rb +25 -0
  42. data/lib/wwmd/viewstate/vs_list.rb +32 -0
  43. data/lib/wwmd/viewstate/vs_pair.rb +27 -0
  44. data/lib/wwmd/viewstate/vs_read_types.rb +11 -0
  45. data/lib/wwmd/viewstate/vs_read_value.rb +33 -0
  46. data/lib/wwmd/viewstate/vs_sparse_array.rb +56 -0
  47. data/lib/wwmd/viewstate/vs_string.rb +29 -0
  48. data/lib/wwmd/viewstate/vs_string_array.rb +37 -0
  49. data/lib/wwmd/viewstate/vs_string_formatted.rb +30 -0
  50. data/lib/wwmd/viewstate/vs_triplet.rb +29 -0
  51. data/lib/wwmd/viewstate/vs_type.rb +21 -0
  52. data/lib/wwmd/viewstate/vs_unit.rb +28 -0
  53. data/lib/wwmd/viewstate/vs_value.rb +33 -0
  54. data/spec/README +3 -0
  55. data/spec/form_array.spec +49 -0
  56. data/spec/spider_csrf_test.spec +28 -0
  57. data/spec/urlparse_test.spec +89 -0
  58. data/tasks/ann.rake +80 -0
  59. data/tasks/bones.rake +20 -0
  60. data/tasks/gem.rake +201 -0
  61. data/tasks/git.rake +40 -0
  62. data/tasks/notes.rake +27 -0
  63. data/tasks/post_load.rake +34 -0
  64. data/tasks/rdoc.rake +51 -0
  65. data/tasks/rubyforge.rake +55 -0
  66. data/tasks/setup.rb +292 -0
  67. data/tasks/spec.rake +54 -0
  68. data/tasks/test.rake +40 -0
  69. data/tasks/zentest.rake +36 -0
  70. metadata +164 -0
@@ -0,0 +1,35 @@
1
+ module WWMD
2
+ class VSClassHelpers < ViewStateUtils
3
+ def to_sym
4
+ self.class.to_s.split(":").last.gsub(/[A-Z]+/,'\1_\0').downcase[1..-1].gsub(/\Avs/,"").to_sym
5
+ end
6
+
7
+ def opcode
8
+ return VIEWSTATE_TYPES.index(self.to_sym)
9
+ end
10
+
11
+ def size
12
+ return @value.size
13
+ end
14
+
15
+ def serialize
16
+ stack = ""
17
+ stack << self.write_byte(self.opcode)
18
+ if self.respond_to?(:typeref)
19
+ stack << self.serialize_type(self.typeref,self.typeval)
20
+ end
21
+ return stack
22
+ end
23
+
24
+ def to_xml
25
+ xml = REXML::Element.new(self.class.to_s.split(":").last)
26
+ if self.respond_to?(:typeref)
27
+ xml.add_attribute("typeref",self.typeref)
28
+ xml.add_attribute("typeval",self.typeval)
29
+ end
30
+ # xml.add_attribute("size",self.size)
31
+ xml
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,213 @@
1
+ module WWMD
2
+ class ViewState
3
+ # complex types
4
+ def pair(t=nil)
5
+ dlog t,"next = #{next_type}"
6
+ VSPair.new(self.deserialize_value,self.deserialize_value)
7
+ end
8
+
9
+ def triplet(t=nil)
10
+ dlog t,"next = #{next_type}"
11
+ VSTriplet.new(self.deserialize_value,self.deserialize_value,self.deserialize_value)
12
+ end
13
+
14
+ def type(t=nil)
15
+ typeref,typeval = self.deserialize_type
16
+ dlog(t,"typeref = #{typeref} typeval = #{typeval}")
17
+ VSType.new(typeref,typeval)
18
+ end
19
+
20
+ def string_formatted(t=nil)
21
+ typeref,typeval = self.deserialize_type
22
+ str = self.read_string
23
+ dlog(t,"typeref = #{typeref} typeval = #{typeval} string = #{str}")
24
+ VSStringFormatted.new(typeref,typeval,str)
25
+ end
26
+
27
+ def int_enum(t=nil)
28
+ typeref,typeval = self.deserialize_type
29
+ index = self.read_7bit_encoded_int
30
+ dlog(t,"typeref = #{typeref} typeval = #{typeval} index = #{index}")
31
+ VSIntEnum.new(typeref,typeval,index)
32
+ end
33
+
34
+ def binary_serialized(t=nil)
35
+ count = self.read_7bit_encoded_int
36
+ dlog(t,count)
37
+ bin = self.read(count)
38
+ me = VSBinarySerialized.new()
39
+ me.set(bin)
40
+ return me
41
+ end
42
+
43
+ def sparse_array(t=nil)
44
+ typeref,typeval = self.deserialize_type
45
+ size = read_7bit_encoded_int
46
+ elems = read_7bit_encoded_int
47
+ dlog(t,"typeref = #{typeref} typeval = #{typeval} size = #{size} elems = #{elems}")
48
+ me = VSSparseArray.new(typeref,typeval,size,elems)
49
+ if elems > size
50
+ raise "Invalid sparse_array"
51
+ end
52
+ (1..elems).each do |i|
53
+ idx = read_7bit_encoded_int
54
+ me.add(idx,self.deserialize_value)
55
+ end
56
+ return me
57
+ end
58
+
59
+ def hashtable(t=nil)
60
+ len = read_7bit_encoded_int
61
+ dlog(t,"len = #{len}")
62
+ me = VSHashtable.new()
63
+ (1..len).each do |i|
64
+ me.add(self.deserialize_value,self.deserialize_value)
65
+ end
66
+ return me
67
+ end
68
+
69
+ def hybrid_dict(t=nil)
70
+ len = read_7bit_encoded_int
71
+ dlog(t,"len = #{len}")
72
+ me = VSHybridDict.new()
73
+ (1..len).each do |i|
74
+ me.add(self.deserialize_value,self.deserialize_value)
75
+ end
76
+ return me
77
+ end
78
+
79
+ def array(t=nil)
80
+ typeref,typeval = self.deserialize_type
81
+ len = read_7bit_encoded_int
82
+ dlog(t,"typeref = #{typeref} typeval = #{typeval} len = #{len}")
83
+ me = VSArray.new(typeref,typeval)
84
+ (1..len).each do |i|
85
+ me.add(self.deserialize_value)
86
+ end
87
+ return me
88
+ end
89
+
90
+ def string_array(t=nil)
91
+ len = read_7bit_encoded_int
92
+ dlog(t,"len = #{len}")
93
+ me = VSStringArray.new()
94
+ (1..len).each do |i|
95
+ str = self.read_string
96
+ me.add(str)
97
+ dlog(t,"string_array_elem: #{str}")
98
+ end
99
+ return me
100
+ end
101
+
102
+ def list(t=nil)
103
+ len = read_7bit_encoded_int
104
+ dlog(t,"len = #{len}")
105
+ me = VSList.new()
106
+ (1..len).each do |i|
107
+ me.add(self.deserialize_value)
108
+ end
109
+ return me
110
+ end
111
+
112
+ def unit(t=nil)
113
+ s1 = read_double
114
+ s2 = read_int32
115
+ dlog(t,"#{s1.to_s(16).rjust(16,"0")},#{s2.to_s(16).rjust(8,"0")}")
116
+ VSUnit.new(s1,s2)
117
+ end
118
+
119
+ def indexed_string(t=nil)
120
+ str = self.read_string
121
+ @indexed_strings << str
122
+ dlog(t,"idx = #{@indexed_strings.size - 1} val = #{str}")
123
+ VSIndexedString.new(str)
124
+ end
125
+
126
+ def indexed_string_ref(t=nil)
127
+ ref = self.read_int
128
+ dlog(t,"ref = #{ref} val = #{@indexed_strings[ref]}")
129
+ VSIndexedStringRef.new(ref)
130
+ end
131
+
132
+ def string(t=nil)
133
+ str = self.read_string
134
+ dlog(t,str)
135
+ VSString.new(str)
136
+ end
137
+
138
+ # VSReadValue types
139
+ def color(t=nil)
140
+ val = self.read_int32
141
+ dlog(t,val.to_s(16))
142
+ VSColor.new(val)
143
+ end
144
+
145
+ def known_color(t=nil)
146
+ index = self.read_7bit_encoded_int
147
+ dlog(t,"index = #{index.to_s(16)}")
148
+ VSKnownColor.new(index)
149
+ end
150
+
151
+ def int16(t=nil)
152
+ val = read_short
153
+ dlog(t,val)
154
+ VSInt16.new(val)
155
+ end
156
+
157
+ def int32(t=nil)
158
+ val = self.read_7bit_encoded_int
159
+ dlog(t,val)
160
+ VSInt32.new(val)
161
+ end
162
+
163
+ def byte(t=nil)
164
+ val = self.read_byte
165
+ dlog(t,val)
166
+ VSByte.new(val)
167
+ end
168
+
169
+ def char(t=nil)
170
+ val = self.read_byte
171
+ dlog(t,val)
172
+ VSChar.new(val)
173
+ end
174
+
175
+ def date_time(t=nil)
176
+ val = self.read_double
177
+ dlog(t,val)
178
+ VSDateTime.new(val)
179
+ end
180
+
181
+ def double(t=nil)
182
+ val = self.read_double
183
+ dlog(t,val)
184
+ VSDouble.new(val)
185
+ end
186
+
187
+ def single(t=nil)
188
+ val = self.read_single
189
+ dlog(t,val)
190
+ VSSingle.new(val)
191
+ end
192
+
193
+ # VSValue types
194
+ def null(t=nil); dlog(t,nil); return VSValue.new(t); end
195
+ def empty_byte(t=nil); dlog(t,nil); return VSValue.new(t); end
196
+ def zeroint32(t=nil); dlog(t,nil); return VSValue.new(t); end
197
+ def bool_true(t=nil); dlog(t,nil); return VSValue.new(t); end
198
+ def bool_false(t=nil); dlog(t,nil); return VSValue.new(t); end
199
+ def empty_color(t=nil); dlog(t,nil); return VSValue.new(t); end
200
+ def empty_unit(t=nil); dlog(t,nil); return VSValue.new(t); end
201
+
202
+ # deserialize_value
203
+ def deserialize_value
204
+ @last_offset = self.offset
205
+ token = self.read_byte # self.read_raw_byte
206
+ raise "Invalid Type #{token.hexify} at #{last_offset}" if not (tsym = VIEWSTATE_TYPES[token])
207
+ nobj = self.send(tsym,token)
208
+ raise "Invalid Class Returned #{nobj.class}" if not VIEWSTATE_TYPES.include?(nobj.opcode)
209
+ return nobj
210
+ end
211
+
212
+ end
213
+ end
@@ -0,0 +1,126 @@
1
+ module WWMD
2
+ class ViewState
3
+ # directly serialize into stack from received xml (the easy way)
4
+ # this is pretty silly but it didn't take me very long so...
5
+
6
+ attr_reader :xmlstack
7
+
8
+ def get_sym(str)
9
+ str.split(":").last.gsub(/[A-Z]+/,'\1_\0').downcase[1..-1].gsub(/\Avs/,"").to_sym
10
+ end
11
+
12
+ def opcode(name,val)
13
+ sym = get_sym(name)
14
+ if sym == :value
15
+ ret = VIEWSTATE_TYPES.index(val.to_sym)
16
+ else
17
+ ret = VIEWSTATE_TYPES.index(sym)
18
+ end
19
+ ret
20
+ end
21
+
22
+ def serialize_hashtable(node)
23
+ tstack = ""
24
+ tstack << self.write_7bit_encoded_int(node['size'].to_i)
25
+ node.children.each do |c|
26
+ next if c.text?
27
+ raise "Invalid Hashtable: got #{c.name}" if not c.name == "Pair"
28
+ end
29
+ tstack
30
+ end
31
+
32
+ def decode_text(node)
33
+ case node['encoding']
34
+ when "quoted-printable"
35
+ node.inner_text.from_qp
36
+ when "base64"
37
+ node.inner_text.b64d
38
+ when "hexify"
39
+ node.inner_text.dehexify
40
+ else
41
+ node.inner_text
42
+ end
43
+ end
44
+
45
+ def write_node(node)
46
+ return false if node.text?
47
+ tstack = ""
48
+ # this is a hack to get sparse_array to work
49
+ return false if ["Pair","Key","Value"].include?(node.name) # skip and fall through
50
+ if ["Index","Size","Elements"].include?(node.name)
51
+ @xmlstack << self.write_7bit_encoded_int(node.inner_text.to_i)
52
+ return false
53
+ end
54
+ if node.name == "Mac"
55
+ @xmlstack << decode_text(node)
56
+ return false
57
+ end
58
+ # end hack
59
+ flag = true # begin; sillyness; rescue => me; end
60
+ case get_sym(node.name)
61
+ when :pair, :triplet, :value, :sparse_array, :type, :string_formatted
62
+ when :int_enum, :known_color, :int32
63
+ tstack << self.write_7bit_encoded_int(node.inner_text.to_i)
64
+ when :int16
65
+ tstack << self.write_short(node.inner_text.to_i)
66
+ when :byte, :char, :indexed_string_ref
67
+ tstack << self.write_byte(node.inner_text.to_i)
68
+ when :color, :single
69
+ tstack << self.write_int32(node.inner_text.to_i)
70
+ when :double, :date_time
71
+ tstack << self.write_double(node.inner_text.to_i)
72
+ when :unit
73
+ tstack << self.write_double(node['dword'].to_i)
74
+ tstack << self.write_single(node['word'].to_i)
75
+ when :list, :string_array, :array
76
+ tstack << self.write_7bit_encoded_int(node['size'].to_i)
77
+ when :string, :indexed_string, :binary_serialized
78
+ flag = false if ([:string_array,:string_formatted].include?(get_sym(node.parent.name)))
79
+ # get encoding
80
+ str = decode_text(node)
81
+ tstack << self.write_7bit_encoded_int(str.size)
82
+ tstack << str
83
+ when :hashtable, :hybrid_dict
84
+ tstack << serialize_hashtable(node)
85
+ else
86
+ raise "Invalid Node:\n#{node.name}"
87
+ end
88
+
89
+ # [flag] is a hack to get around string_array and string_formatted emitting opcodes
90
+ @xmlstack << self.write_byte(opcode(node.name,node.inner_text)) if flag
91
+ if node.has_attribute?("typeref")
92
+ if node['typeref'].to_i == 0x2b
93
+ @xmlstack << self.serialize_type(node['typeref'].to_i,node['typeval'].to_i)
94
+ else
95
+ @xmlstack << self.serialize_type(node['typeref'].to_i,node['typeval'])
96
+ end
97
+ end
98
+ @xmlstack << tstack
99
+ end
100
+
101
+ def serialize_xml(node)
102
+ begin
103
+ write_node(node)
104
+ rescue => e
105
+ STDERR.puts "ERROR parsing node:\n#{node.to_s}"
106
+ raise e
107
+ end
108
+ node.children.each do |c|
109
+ serialize_xml(c)
110
+ end
111
+ end
112
+
113
+ def from_xml(xml)
114
+ @xmlstack = ""
115
+ doc = Nokogiri::XML.parse(xml)
116
+ root = doc.root
117
+ raise "Invalid ViewState Version" if not root.has_attribute?("version")
118
+ @xmlstack << root['version'].b64d
119
+ root.children.each do |c|
120
+ serialize_xml(c)
121
+ end
122
+ self.deserialize(@xmlstack.b64e)
123
+ end
124
+
125
+ end
126
+ end
@@ -0,0 +1,51 @@
1
+ module WWMD
2
+ # private const byte Marker_Format = 0xff;
3
+ # private const byte Marker_Version_1 = 1;
4
+ # private const int StringTableSize = 0xff;
5
+
6
+ VIEWSTATE_MAGIC = ["\xff\x01"] unless defined?(VIEWSTATE_MAGIC)
7
+
8
+ VIEWSTATE_TYPES = {
9
+ # System.Web.UI.LosFormatter
10
+ # System.Web.UI.ObjectStateFormatter
11
+ # .DeserializeValue
12
+
13
+ 0x00 => :debug, ##X debugging
14
+ 0x01 => :int16, #RX private const byte Token_Int16 = 1;
15
+ 0x02 => :int32, #RX private const byte Token_Int32 = 2;
16
+ 0x03 => :byte, #RX private const byte Token_Byte = 3;
17
+ 0x04 => :char, #RX private const byte Token_Char = 4;
18
+ 0x05 => :string, ##X private const byte Token_String = 5;
19
+ 0x06 => :date_time, #RX private const byte Token_DateTime = 6;
20
+ 0x07 => :double, #RX private const byte Token_Double = 7;
21
+ 0x08 => :single, #RX private const byte Token_Single = 8;
22
+ 0x09 => :color, ##X private const byte Token_Color = 9;
23
+ 0x0a => :known_color, ##X private const byte Token_KnownColor = 10;
24
+ 0x0b => :int_enum, ##X private const byte Token_IntEnum = 11;
25
+ 0x0c => :empty_color, #VX private const byte Token_EmptyColor = 12;
26
+ 0x0f => :pair, ##X private const byte Token_Pair = 15;
27
+ 0x10 => :triplet, ##X private const byte Token_Triplet = 0x10;
28
+ 0x14 => :array, ##X private const byte Token_Array = 20;
29
+ 0x15 => :string_array, ##X private const byte Token_StringArray = 0x15;
30
+ 0x16 => :list, ##X private const byte Token_ArrayList = 0x16;
31
+ 0x17 => :hashtable, ##X private const byte Token_Hashtable = 0x17
32
+ 0x18 => :hybrid_dict, ##X private const byte Token_HybridDictionary = 0x18;
33
+ 0x19 => :type, ##X private const byte Token_Type = 0x19;
34
+ 0x1b => :unit, ##X private const byte Token_Unit = 0x1b;
35
+ 0x1c => :empty_unit, #VX private const byte Token_EmptyUnit = 0x1c;
36
+ 0x1e => :indexed_string, ##X private const byte Token_IndexedStringAdd = 30;
37
+ 0x1f => :indexed_string_ref, ##X private const byte Token_IndexedString = 0x1f;
38
+ 0x28 => :string_formatted, ##X private const byte Token_StringFormatted = 40;
39
+ 0x29 => :typeref_add, ##X private const byte Token_TypeRefAdd = 0x29;
40
+ 0x2a => :typeref_add_local, ##X private const byte Token_TypeRefAddLocal = 0x2a;
41
+ 0x2b => :typeref, ##X private const byte Token_TypeRef = 0x2b;
42
+ 0x32 => :binary_serialized, ##X private const byte Token_BinarySerialized = 50;
43
+ 0x3c => :sparse_array, ##X private const byte Token_SparseArray = 60;
44
+ 0x64 => :null, #VX private const byte Token_Null = 100;
45
+ 0x65 => :empty_byte, #VX private const byte Token_EmptyString = 0x65;
46
+ 0x66 => :zeroint32, #VX private const byte Token_ZeroInt32 = 0x66;
47
+ 0x67 => :bool_true, #VX private const byte Token_True = 0x67;
48
+ 0x68 => :bool_false, #VX private const byte Token_False = 0x68;
49
+ } unless defined?(VIEWSTATE_TYPES)
50
+
51
+ end
@@ -0,0 +1,157 @@
1
+ module WWMD
2
+ class ViewStateUtils
3
+
4
+ def putd(msg)
5
+ puts(msg) if self.debug
6
+ end
7
+
8
+ def slog(obj,msg=nil)
9
+ raise "No @value" if not obj.respond_to?(:value)
10
+ raise "No @size" if not obj.respond_to?(:size)
11
+ putd "#{@stack.size.to_s(16).rjust(8,"0")} [0x#{obj.opcode.to_s(16)}] #{obj.class}: #{msg}"
12
+ end
13
+
14
+ def dlog(t,msg)
15
+ raise "null token passed to dlog()" if t.nil?
16
+ putd "#{self.last_offset} [0x#{t.to_s(16).rjust(2,"0")}] #{VIEWSTATE_TYPES[t]}: #{msg}"
17
+ end
18
+
19
+ def write_7bit_encoded_int(val)
20
+ s = ""
21
+ while (val >= 0x80) do
22
+ s << [val | 0x80].pack("C")
23
+ val = val >> 7
24
+ end
25
+ s << [val].pack("C")
26
+ return s
27
+ end
28
+
29
+ # why oh why did I have to go find this?
30
+ # System.IO.BinaryReader.Read7BitEncodedInt
31
+ def read_7bit_encoded_int(buf=nil)
32
+ l = 0 # length
33
+ s = 0 # shift
34
+ b = "" # byte
35
+ buf = buf.scan(/./m) if buf
36
+ begin
37
+ if not buf
38
+ b = self.read_int
39
+ else
40
+ b = buf.shift.unpack("C").first
41
+ end
42
+ l |= (b & 0x7f) << s
43
+ s += 7
44
+ end while ((b & 0x80) != 0)
45
+ return l
46
+ end
47
+
48
+ def read_string
49
+ len = read_7bit_encoded_int
50
+ starr = []
51
+ (1..len).each { |i| starr << @bufarr.shift }
52
+ return starr.to_s
53
+ # @bufarr.slice!(0..(len - 1)).join("")
54
+ end
55
+
56
+ def read(count)
57
+ @bufarr.slice!(0..(count - 1)).join("")
58
+ end
59
+
60
+ def read_int
61
+ @bufarr.shift.unpack("C").first
62
+ end
63
+ alias_method :read_byte, :read_int
64
+
65
+ def write_int(val)
66
+ [val].pack("C")
67
+ end
68
+ alias_method :write_byte, :write_int
69
+
70
+ def read_short
71
+ self.read(2).unpack("S").first
72
+ end
73
+
74
+ def write_short(val)
75
+ [val].pack("n")
76
+ end
77
+
78
+ def read_int32
79
+ @bufarr.slice!(0..3).join("").unpack("L").first
80
+ end
81
+ alias_method :read_single, :read_int32
82
+
83
+ def write_int32(val)
84
+ [val].pack("I")
85
+ end
86
+ alias_method :write_single, :write_int32
87
+
88
+ def read_double
89
+ @bufarr.slice!(0..7).join("").unpack("Q").first
90
+ end
91
+
92
+ def write_double(val)
93
+ [val].pack("Q")
94
+ end
95
+
96
+ def magic?
97
+ @magic = [@bufarr.shift,@bufarr.shift].join("")
98
+ VIEWSTATE_MAGIC.include?(@magic)
99
+ end
100
+
101
+ def read_raw_byte
102
+ @bufarr.shift
103
+ end
104
+
105
+ def serialize_type(op,ref)
106
+ op_str = [op].pack("C")
107
+ s = op_str
108
+ case op
109
+ when VIEWSTATE_TYPES.index(:typeref)
110
+ s << write_7bit_encoded_int(ref)
111
+ when VIEWSTATE_TYPES.index(:typeref_add_local)
112
+ s << write_7bit_encoded_int(ref.size)
113
+ s << ref
114
+ when VIEWSTATE_TYPES.index(:typeref_add)
115
+ s << write_7bit_encoded_int(ref.size)
116
+ s << ref
117
+ else
118
+ raise "Invalid Type Error #{op.to_s(16)}"
119
+ end
120
+ return s
121
+ end
122
+
123
+ def deserialize_type(t=nil)
124
+ op = self.read_byte
125
+ case op
126
+ when VIEWSTATE_TYPES.index(:typeref)
127
+ type = read_7bit_encoded_int
128
+ return [op,type]
129
+ when VIEWSTATE_TYPES.index(:typeref_add_local)
130
+ name = read_string
131
+ return [op,name]
132
+ when VIEWSTATE_TYPES.index(:typeref_add)
133
+ name = read_string
134
+ return [op,name]
135
+ else
136
+ raise "Invalid Type Error 0x#{op.to_s(16)}"
137
+ end
138
+ end
139
+
140
+ def offset(cur=nil)
141
+ (self.size - @bufarr.size).to_s(16).rjust(8,"0")
142
+ end
143
+
144
+ def throw(t=nil)
145
+ STDERR.puts "==== Error at Type 0x#{t.to_s(16).rjust(2,"0")}"
146
+ STDERR.puts "offset: #{self.offset}"
147
+ STDERR.puts "left: #{@bufarr.size}"
148
+ STDERR.puts @bufarr[0..31].join("").hexdump
149
+ end
150
+
151
+ def next_type
152
+ t = @bufarr.first.unpack("C").first
153
+ throw(t) if not VIEWSTATE_TYPES.include?(t)
154
+ VIEWSTATE_TYPES[t]
155
+ end
156
+ end
157
+ end