php-serialization 0.5.3 → 1.0.0

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.
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.4.6
3
+ # This file is automatically generated by Racc 1.4.12
4
4
  # from Racc grammer file "".
5
5
  #
6
6
 
@@ -11,11 +11,11 @@ require 'php_serialization/tokenizer'
11
11
  module PhpSerialization
12
12
  class Unserializer < Racc::Parser
13
13
 
14
- module_eval(<<'...end unserializer.y/module_eval...', 'unserializer.y', 69)
14
+ module_eval(<<'...end unserializer.y/module_eval...', 'unserializer.y', 81)
15
15
  def initialize(tokenizer_klass = Tokenizer)
16
16
  @tokenizer_klass = tokenizer_klass
17
17
  end
18
-
18
+
19
19
  def run(string)
20
20
  @tokenizer = @tokenizer_klass.new(string)
21
21
  yyparse(@tokenizer, :each)
@@ -23,7 +23,7 @@ module_eval(<<'...end unserializer.y/module_eval...', 'unserializer.y', 69)
23
23
  ensure
24
24
  @tokenizer = nil
25
25
  end
26
-
26
+
27
27
  def next_token
28
28
  @tokenizer.next_token
29
29
  end
@@ -31,58 +31,58 @@ module_eval(<<'...end unserializer.y/module_eval...', 'unserializer.y', 69)
31
31
  ##### State transition tables begin ###
32
32
 
33
33
  racc_action_table = [
34
- 5, 6, 19, 20, 9, 11, 13, 21, 1, 5,
35
- 6, 4, 22, 9, 11, 13, 23, 1, 5, 6,
36
- 4, 24, 9, 11, 13, 25, 1, 26, 46, 4,
37
- 5, 6, 27, 28, 9, 11, 13, 29, 1, 30,
38
- 52, 4, 18, 32, 33, 34, 35, 36, 37, 38,
39
- 39, 40, 41, 43, 45, 17, 49, 16, 31 ]
34
+ 9, 10, 19, 20, 11, 12, 13, 21, 14, 9,
35
+ 10, 15, 22, 11, 12, 13, 23, 14, 9, 10,
36
+ 15, 24, 11, 12, 13, 25, 14, 26, 46, 15,
37
+ 9, 10, 27, 28, 11, 12, 13, 29, 14, 30,
38
+ 51, 15, 18, 32, 33, 34, 35, 36, 37, 38,
39
+ 39, 40, 41, 43, 17, 47, 16, 49, 31 ]
40
40
 
41
41
  racc_action_check = [
42
- 0, 0, 7, 8, 0, 0, 0, 9, 0, 48,
43
- 48, 0, 10, 48, 48, 48, 11, 48, 44, 44,
44
- 48, 12, 44, 44, 44, 13, 44, 14, 44, 44,
45
- 51, 51, 15, 16, 51, 51, 51, 17, 51, 18,
46
- 51, 51, 6, 21, 23, 25, 28, 29, 34, 35,
47
- 36, 37, 38, 41, 43, 4, 45, 1, 19 ]
42
+ 0, 0, 4, 5, 0, 0, 0, 6, 0, 45,
43
+ 45, 0, 10, 45, 45, 45, 11, 45, 42, 42,
44
+ 45, 12, 42, 42, 42, 13, 42, 14, 42, 42,
45
+ 50, 50, 15, 16, 50, 50, 50, 22, 50, 23,
46
+ 50, 50, 3, 25, 26, 27, 32, 33, 34, 35,
47
+ 36, 37, 39, 41, 2, 43, 1, 47, 24 ]
48
48
 
49
49
  racc_action_pointer = [
50
- -3, 52, nil, nil, 50, nil, 37, 2, 1, 2,
51
- 10, 11, 19, 20, 25, 30, 27, 31, 33, 58,
52
- nil, 37, nil, 38, nil, 39, nil, nil, 41, 42,
53
- nil, nil, nil, nil, 43, 39, 38, 41, 47, nil,
54
- nil, 47, nil, 49, 15, 44, nil, nil, 6, nil,
55
- nil, 27, nil ]
50
+ -3, 56, 52, 40, 0, 1, 5, nil, nil, nil,
51
+ 7, 11, 16, 20, 22, 27, 33, nil, nil, nil,
52
+ nil, nil, 31, 33, 52, 37, 38, 39, nil, nil,
53
+ nil, nil, 41, 42, 43, 39, 40, 39, nil, 47,
54
+ nil, 47, 15, 50, nil, 6, nil, 45, nil, nil,
55
+ 27, nil ]
56
56
 
57
57
  racc_action_default = [
58
- -19, -19, -6, -7, -19, -8, -19, -19, -19, -19,
59
- -19, -19, -19, -19, -19, -19, -19, -19, -19, -19,
60
- -1, -19, -2, -19, -3, -19, -4, -5, -19, -19,
61
- -9, 53, -10, -11, -19, -19, -19, -19, -19, -17,
62
- -12, -19, -15, -19, -19, -19, -18, -14, -19, -15,
63
- -16, -19, -13 ]
58
+ -18, -18, -18, -18, -18, -18, -18, -6, -7, -8,
59
+ -18, -18, -18, -18, -18, -18, -18, -1, -2, -3,
60
+ -4, -5, -18, -18, -18, -18, -18, -18, 52, -9,
61
+ -10, -11, -18, -18, -18, -18, -18, -18, -12, -18,
62
+ -15, -18, -18, -18, -14, -18, -17, -18, -16, -15,
63
+ -18, -13 ]
64
64
 
65
65
  racc_goto_table = [
66
- 7, 44, 42, nil, nil, nil, nil, nil, 51, nil,
67
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
66
+ 1, 42, nil, nil, nil, nil, nil, nil, nil, nil,
67
+ 50, nil, nil, nil, nil, nil, nil, nil, nil, nil,
68
68
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
69
69
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
70
- nil, nil, nil, nil, nil, nil, nil, nil, 50 ]
70
+ nil, nil, nil, nil, nil, 48 ]
71
71
 
72
72
  racc_goto_check = [
73
- 1, 9, 11, nil, nil, nil, nil, nil, 9, nil,
73
+ 1, 9, nil, nil, nil, nil, nil, nil, nil, nil,
74
+ 9, nil, nil, nil, nil, nil, nil, nil, nil, nil,
74
75
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
75
76
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
76
- nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
77
- nil, nil, nil, nil, nil, nil, nil, nil, 1 ]
77
+ nil, nil, nil, nil, nil, 1 ]
78
78
 
79
79
  racc_goto_pointer = [
80
- nil, 0, nil, nil, nil, nil, nil, nil, nil, -41,
81
- nil, -37 ]
80
+ nil, 0, nil, nil, nil, nil, nil, nil, nil, -39,
81
+ nil ]
82
82
 
83
83
  racc_goto_default = [
84
- nil, 48, 8, 10, 12, 14, 15, 2, 3, nil,
85
- 47, nil ]
84
+ nil, 45, 2, 3, 4, 5, 6, 7, 8, nil,
85
+ 44 ]
86
86
 
87
87
  racc_reduce_table = [
88
88
  0, 0, :racc_error,
@@ -102,12 +102,11 @@ racc_reduce_table = [
102
102
  2, 24, :_reduce_14,
103
103
  0, 24, :_reduce_15,
104
104
  2, 25, :_reduce_16,
105
- 0, 26, :_reduce_17,
106
- 8, 22, :_reduce_18 ]
105
+ 7, 22, :_reduce_17 ]
107
106
 
108
- racc_reduce_n = 19
107
+ racc_reduce_n = 18
109
108
 
110
- racc_shift_n = 53
109
+ racc_shift_n = 52
111
110
 
112
111
  racc_token_table = {
113
112
  false => 0,
@@ -169,11 +168,10 @@ Racc_token_to_s_table = [
169
168
  "integer",
170
169
  "double",
171
170
  "string",
172
- "array",
171
+ "assoc_array",
173
172
  "object",
174
173
  "attribute_list",
175
- "attribute",
176
- "@1" ]
174
+ "attribute" ]
177
175
 
178
176
  Racc_debug_parser = false
179
177
 
@@ -269,13 +267,23 @@ module_eval(<<'.,.,', 'unserializer.y', 29)
269
267
  def _reduce_13(val, _values, result)
270
268
  if eval("defined?(#{val[4]})")
271
269
  result = Object.const_get(val[4]).new
272
-
270
+
273
271
  val[9].each do |(attr_name, value)|
274
- result.instance_variable_set("@#{attr_name.gsub(/(^\*)|\0/, '')}", value)
272
+ # Protected and private attributes will have a \0..\0 prefix
273
+ attr_name = attr_name.gsub(/\A\\0[^\\]+\\0/, '')
274
+ result.instance_variable_set("@#{attr_name}", value)
275
275
  end
276
276
  else
277
277
  klass_name = val[4].gsub(/^Struct::/, '')
278
- result = Struct.new(klass_name, *val[9].map { |(k,v)| k.gsub(/(^\*)|\0/, '').to_sym }).new(*val[9].map { |(k,v)| v })
278
+ attr_names, values = [], []
279
+
280
+ val[9].each do |(attr_name, value)|
281
+ # Protected and private attributes will have a \0..\0 prefix
282
+ attr_names << attr_name.gsub(/\A\\0[^\\]+\\0/, '')
283
+ values << value
284
+ end
285
+
286
+ result = Struct.new(klass_name, *attr_names).new(*values)
279
287
  result.instance_variable_set("@_php_class", klass_name)
280
288
  end
281
289
 
@@ -283,42 +291,37 @@ module_eval(<<'.,.,', 'unserializer.y', 29)
283
291
  end
284
292
  .,.,
285
293
 
286
- module_eval(<<'.,.,', 'unserializer.y', 43)
294
+ module_eval(<<'.,.,', 'unserializer.y', 53)
287
295
  def _reduce_14(val, _values, result)
288
296
  result = val[0] << val[1]
289
297
  result
290
298
  end
291
299
  .,.,
292
300
 
293
- module_eval(<<'.,.,', 'unserializer.y', 44)
301
+ module_eval(<<'.,.,', 'unserializer.y', 54)
294
302
  def _reduce_15(val, _values, result)
295
303
  result = []
296
304
  result
297
305
  end
298
306
  .,.,
299
307
 
300
- module_eval(<<'.,.,', 'unserializer.y', 47)
308
+ module_eval(<<'.,.,', 'unserializer.y', 57)
301
309
  def _reduce_16(val, _values, result)
302
- @numeric_array = false unless val[0].is_a?(Integer); result = [val[0], val[1]]
310
+ result = val
303
311
  result
304
312
  end
305
313
  .,.,
306
314
 
307
- module_eval(<<'.,.,', 'unserializer.y', 50)
315
+ module_eval(<<'.,.,', 'unserializer.y', 62)
308
316
  def _reduce_17(val, _values, result)
309
- @numeric_array = true
310
- result
311
- end
312
- .,.,
317
+ # Checks if the keys are a sequence of integers
318
+ idx = -1
319
+ arr = val[5].all? { |(k,v)| k == (idx += 1) }
313
320
 
314
- module_eval(<<'.,.,', 'unserializer.y', 52)
315
- def _reduce_18(val, _values, result)
316
- if @numeric_array
317
- result = []
318
- val[6].each { |(i,v)| result[i] = v }
321
+ if arr
322
+ result = val[5].map { |(k,v)| v }
319
323
  else
320
- result = {}
321
- val[6].each { |(k, v)| result[k] = v}
324
+ result = Hash[val[5]]
322
325
  end
323
326
 
324
327
  result
@@ -6,70 +6,82 @@ rule
6
6
  | integer ';' { @object = val[0] }
7
7
  | double ';' { @object = val[0] }
8
8
  | string ';' { @object = val[0] }
9
- | array { @object = val[0] }
9
+ | assoc_array { @object = val[0] }
10
10
  | object { @object = val[0] }
11
- ;
12
-
11
+ ;
12
+
13
13
  null : 'N' { result = nil }
14
14
  ;
15
-
15
+
16
16
  bool : 'b' ':' NUMBER { result = Integer(val[2]) > 0 }
17
17
  ;
18
-
18
+
19
19
  integer : 'i' ':' NUMBER { result = Integer(val[2]) }
20
20
  ;
21
-
21
+
22
22
  double : 'd' ':' NUMBER { result = Float(val[2]) }
23
23
  ;
24
-
24
+
25
25
  string : 's' ':' NUMBER ':' STRING { result = val[4] }
26
26
  ;
27
-
28
- object : 'O' ':' NUMBER ':' STRING ':' NUMBER ':' '{' attribute_list '}'
29
- {
27
+
28
+ object : 'O' ':' NUMBER ':' STRING ':' NUMBER ':' '{' attribute_list '}'
29
+ {
30
30
  if eval("defined?(#{val[4]})")
31
31
  result = Object.const_get(val[4]).new
32
-
32
+
33
33
  val[9].each do |(attr_name, value)|
34
- result.instance_variable_set("@#{attr_name.gsub(/(^\*)|\0/, '')}", value)
34
+ # Protected and private attributes will have a \0..\0 prefix
35
+ attr_name = attr_name.gsub(/\A\\0[^\\]+\\0/, '')
36
+ result.instance_variable_set("@#{attr_name}", value)
35
37
  end
36
38
  else
37
39
  klass_name = val[4].gsub(/^Struct::/, '')
38
- result = Struct.new(klass_name, *val[9].map { |(k,v)| k.gsub(/(^\*)|\0/, '').to_sym }).new(*val[9].map { |(k,v)| v })
40
+ attr_names, values = [], []
41
+
42
+ val[9].each do |(attr_name, value)|
43
+ # Protected and private attributes will have a \0..\0 prefix
44
+ attr_names << attr_name.gsub(/\A\\0[^\\]+\\0/, '')
45
+ values << value
46
+ end
47
+
48
+ result = Struct.new(klass_name, *attr_names).new(*values)
39
49
  result.instance_variable_set("@_php_class", klass_name)
40
50
  end
41
51
  }
42
52
  ;
43
53
 
44
54
  attribute_list : attribute_list attribute { result = val[0] << val[1] }
45
- | { result = [] }
55
+ | { result = [] }
46
56
  ;
47
57
 
48
- attribute : data data { @numeric_array = false unless val[0].is_a?(Integer); result = [val[0], val[1]] }
58
+ attribute : data data { result = val }
49
59
  ;
50
-
51
- array : 'a' ':' NUMBER ':' '{' { @numeric_array = true } attribute_list '}'
52
- {
53
- if @numeric_array
54
- result = []
55
- val[6].each { |(i,v)| result[i] = v }
60
+
61
+ assoc_array : 'a' ':' NUMBER ':' '{' attribute_list '}'
62
+ {
63
+ # Checks if the keys are a sequence of integers
64
+ idx = -1
65
+ arr = val[5].all? { |(k,v)| k == (idx += 1) }
66
+
67
+ if arr
68
+ result = val[5].map { |(k,v)| v }
56
69
  else
57
- result = {}
58
- val[6].each { |(k, v)| result[k] = v}
70
+ result = Hash[val[5]]
59
71
  end
60
72
  }
61
73
  ;
62
-
74
+
63
75
  end
64
76
 
65
77
  ---- header ----
66
78
  require 'php_serialization/tokenizer'
67
79
 
68
- ---- inner ----
80
+ ---- inner ----
69
81
  def initialize(tokenizer_klass = Tokenizer)
70
82
  @tokenizer_klass = tokenizer_klass
71
83
  end
72
-
84
+
73
85
  def run(string)
74
86
  @tokenizer = @tokenizer_klass.new(string)
75
87
  yyparse(@tokenizer, :each)
@@ -77,7 +89,7 @@ require 'php_serialization/tokenizer'
77
89
  ensure
78
90
  @tokenizer = nil
79
91
  end
80
-
92
+
81
93
  def next_token
82
94
  @tokenizer.next_token
83
95
  end
@@ -0,0 +1,3 @@
1
+ module PhpSerialization
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'php_serialization/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "php-serialization"
8
+ spec.version = PhpSerialization::VERSION
9
+ spec.authors = ["Rodrigo Kochenburger"]
10
+ spec.email = ["divoxx@gmail.com"]
11
+ spec.summary = %q{Pure Ruby implementation of php's methods: serialize() and unserializer()}
12
+ spec.description = %q{Pure Ruby implementation of php's methods: serialize() and unserializer()}
13
+ spec.homepage = "https://github.com/divoxx/ruby-php-serialization"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0.0"
24
+
25
+ spec.add_dependency "racc"
26
+ end
@@ -0,0 +1,23 @@
1
+ require "php_serialization"
2
+
3
+ RSpec.describe "Session serialization" do
4
+ it "should store session correctly" do
5
+ data = PhpSessionSerialization.load("userId|i:123;store|s:3:\"foo\";someArr|a:2:{i:0;b:1;i:1;s:3:\"foo\";}")
6
+ expect(data).to eq(
7
+ "userId" => 123,
8
+ "store" => "foo",
9
+ "someArr" => [true, "foo"]
10
+ )
11
+ end
12
+
13
+ it "should dump a hash as session" do
14
+ session_hash = {
15
+ "userId" => 123,
16
+ "store" => "foo",
17
+ "someArr" => [true, "foo"]
18
+ }
19
+
20
+ data = PhpSessionSerialization.load(PhpSessionSerialization.dump(session_hash))
21
+ expect(data).to eq(session_hash)
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ require "php_serialization/serializer"
2
+
3
+ RSpec.describe PhpSerialization::Serializer do
4
+ it "should serialize a integer" do
5
+ expect(subject.run(10)).to eq("i:10;")
6
+ end
7
+
8
+ it "should serialize a string" do
9
+ expect(subject.run("Name")).to eq('s:4:"Name";')
10
+ end
11
+
12
+ it "should serialize a symbol string" do
13
+ expect(subject.run(:name)).to eq('s:4:"name";')
14
+ end
15
+
16
+ it "should serialize true" do
17
+ expect(subject.run(true)).to eq('b:1;')
18
+ end
19
+
20
+ it "should serialize false" do
21
+ expect(subject.run(false)).to eq('b:0;')
22
+ end
23
+
24
+ it "should serialize nil" do
25
+ expect(subject.run(nil)).to eq('N;')
26
+ end
27
+
28
+ it "should unzerialize an array" do
29
+ expect(subject.run([true, "foo"])).to eq('a:2:{i:0;b:1;i:1;s:3:"foo";}')
30
+ end
31
+
32
+ it "should serialize a hash" do
33
+ expect(subject.run("name" => "Rodrigo", "age" => 23)).to eq('a:2:{s:4:"name";s:7:"Rodrigo";s:3:"age";i:23;}')
34
+ end
35
+
36
+ it "should serialize object with class existant" do
37
+ class Person
38
+ attr_accessor :name, :age
39
+ end
40
+
41
+ person = Person.new
42
+ person.name = "Rodrigo"
43
+ person.age = 23
44
+
45
+ expect(subject.run(person)).to eq("O:6:\"Person\":2:{s:3:\"age\";i:23;s:4:\"name\";s:7:\"Rodrigo\";}")
46
+
47
+ Object.send(:remove_const, :Person)
48
+ end
49
+ end