Module: Psf

Defined in:
lib/psf/php_serial.rb,
lib/psf/version.rb

Overview

PHP serialization library that can parse and generate PHP's serialization format including PHP sessions specific format.

Thos module is a patched, modified and enhanced version of jurias/php-serial (under MIT license).

Constant Summary collapse

VERSION =

Version of php-serialized-formatter library and app

'0.0.1'

Class Method Summary collapse

Class Method Details

.extract_until!(str, char) ⇒ String

Return all characters up to the first occurrence of char. Truncates those characters from input string.

Parameters:

Returns:



143
144
145
146
147
148
149
150
151
# File 'lib/psf/php_serial.rb', line 143

def self.extract_until!(str, char)
  extracted = ''
  while (c = str.slice!(0))
    break if c == char

    extracted << c
  end
  extracted
end

.serialize(var) ⇒ String

Serializes a ruby object into PHP serialized format.

Parameters:

  • var (NilClass|Fixnum|Float|TrueClass|FalseClass|String|Array|Hash|Object)

Returns:



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/psf/php_serial.rb', line 15

def self.serialize(var)
  val = ''
  case var.class.to_s
  when 'NilClass'
    val = 'N;'
  when 'Integer', 'Fixnum', 'Bignum'
    val = "i:#{var};"
  when 'Float'
    val = "d:#{var};"
  when 'TrueClass'
    val = 'b:1;'
  when 'FalseClass'
    val = 'b:0;'
  when 'String', 'Symbol'
    val = "s:#{var.to_s.bytesize}:\"#{var}\";"
  when 'Array'
    val = "a:#{var.length}:{"
    var.length.times do |index|
      val += serialize(index) + serialize(var[index])
    end
    val += '}'
  when 'Hash'
    val = "a:#{var.length}:{"
    var.each do |item_key, item_value|
      val += serialize(item_key) + serialize(item_value)
    end
    val += '}'
  else
    klass = var.class.to_s
    val = "O:#{klass.length}:\"#{klass}\":#{var.instance_variables.length}:{"
    var.instance_variables.each do |ivar|
      ivar = ivar.to_s
      ivar.slice!(0)
      val += serialize(ivar) + serialize(var.send(ivar))
    end
    val += '}'
  end
  val
end

.serialize_session(hash) ⇒ String

Serializes a hash into PHP session.

Parameters:

  • hash (Hash)

Returns:



58
59
60
61
62
63
64
# File 'lib/psf/php_serial.rb', line 58

def self.serialize_session(hash)
  serialized_session = ''
  hash.each do |key, value|
    serialized_session += "#{key}|#{serialize(value)}"
  end
  serialized_session
end

.unserialize(data = '') ⇒ NilClass|Fixnum|Float|TrueClass|FalseClass|String|Array|Hash|Object

Unserializes a string up to the first valid serialized instance.

Parameters:

  • data (String) (defaults to: '')

Returns:

  • (NilClass|Fixnum|Float|TrueClass|FalseClass|String|Array|Hash|Object)


87
88
89
# File 'lib/psf/php_serial.rb', line 87

def self.unserialize(data = '')
  unserialize!(data.strip)
end

.unserialize!(data = '') ⇒ NilClass|Fixnum|Float|TrueClass|FalseClass|String|Array|Hash|Object

Unserializes recursively. Consumes the input string.

Parameters:

  • data (String) (defaults to: '')

Returns:

  • (NilClass|Fixnum|Float|TrueClass|FalseClass|String|Array|Hash|Object)


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/psf/php_serial.rb', line 94

def self.unserialize!(data = '')
  var_type = data.slice!(0)
  data.slice!(0)
  case var_type
  when 'N'
    value = nil
  when 'b'
    value = (extract_until!(data, ';') == '1')
  when 's'
    length = extract_until!(data, ':').to_i
    extract_until!(data, '"')
    value = data.byteslice!(0, length)
    extract_until!(data, ';')
  when 'i'
    value = extract_until!(data, ';').to_i
  when 'd'
    value = extract_until!(data, ';').to_f
  when 'a'
    value = {}
    length = extract_until!(data, ':').to_i
    extract_until!(data, '{')
    length.times do
      key = unserialize!(data)
      value[key] = unserialize!(data)
    end
    extract_until!(data, '}')
    # if keys are sequential numbers, return array
    value = value.values if (Array(0..value.length - 1) == value.keys) && !value.empty?
  when 'O'
    value = {}
    length = extract_until!(data, ':').to_i
    extract_until!(data, '"')
    value['class'] = data.slice!(0, length)
    extract_until!(data, ':')
    length = extract_until!(data, ':').to_i
    extract_until!(data, '{')
    length.times do
      key = unserialize!(data)
      value[key] = unserialize!(data)
    end
  end
  value
end

.unserialize_session(data) ⇒ Hash

Unserializes a PHP session.

Parameters:

Returns:

  • (Hash)


69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/psf/php_serial.rb', line 69

def self.unserialize_session(data)
  begin
    data = data.strip
  rescue Encoding::CompatibilityError
    data = data.encode('UTF-8', invalid: :replace, undef: :replace).strip if data.encoding == Encoding::UTF_8
  end
  hash = {}

  until data.empty?
    key = extract_until!(data, '|')
    hash[key] = unserialize!(data)
  end
  hash
end