miketracy-wwmd 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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