forked from Blogestudio/Fix-Serialization
-
Notifications
You must be signed in to change notification settings - Fork 2
/
fix-serialization.php
executable file
·163 lines (124 loc) · 3.95 KB
/
fix-serialization.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/php
<?php
/*
* Blogestudio Fix Serialization 1.2
* Fixer script of length attributes for serialized strings (e.g. Wordpress databases)
* License: GPL version 3 or later - http://www.gnu.org/licenses/gpl.txt
* By Pau Iglesias
* http://blogestudio.com
*
* Inspiration and regular expression code base from David Coveney:
* http://davidcoveney.com/575/php-serialization-fix-for-wordpress-migrations/
*
* Usage:
*
* /usr/bin/php fix-serialization.php my-sql-file.sql
*
* Versions:
*
* 1.0 2011-08-03 Initial release
* 1.1 2011-08-18 Support for backslashed quotes, added some code warnings
* 1.2 2011-09-29 Support for null or zero length strings after preg_replace is called, and explain how to handle these errors
*
* Knowed errors:
*
* - Memory size exhausted
* Allowed memory size of 67108864 bytes exhausted (tried to allocate 35266489 bytes)
* How to fix: update php.ini memory_limit to 512M or more, and restart cgi service or web server
*
* - Function preg_replace returns null or 0 length string
* If preg_last_error = PREG_BACKTRACK_LIMIT_ERROR (value 2), increase pcre.backtrack_limit in php.ini (by default 100k, change to 2M by example)
* Same way for others preg_last_error codes: http://www.php.net/manual/en/function.preg-last-error.php
*
* TODO next versions
*
* - Check if needed UTF-8 support detecting and adding u PCRE modifier
*
*/
// Unescape to avoid dump-text issues
function unescape_mysql($value) {
return str_replace(array("\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"'),
array("\\", "\0", "\n", "\r", "\x1a", "'", '"'),
$value);
}
// Fix strange behaviour if you have escaped quotes in your replacement
function unescape_quotes($value) {
return str_replace('\"', '"', $value);
}
// Check command line arguments
if (!(isset($argv) && isset($argv[1]))) {
// Error
echo 'Error: no input file specified'."\n\n";
// With arguments
} else {
// Compose path from argument
$path = $argv[1]; // removed dirname allows to use relative paths when script called from other working directory
if (!file_exists($path)) {
// Error
echo 'Error: input file does not exists'."\n";
echo $path."\n\n";
// File exists
} else {
// Get file contents
if (!($fp = fopen($path, 'r'))) {
// Error
echo 'Error: can`t open input file for read'."\n";
echo $path."\n\n";
// File opened for read
} else {
// Initializations
$do_preg_replace = false;
// Copy data
if (!($data = fread($fp, filesize($path)))) {
// Error
echo 'Error: can`t read entire data from input file'."\n";
echo $path."\n\n";
// Check data
} elseif (!(isset($data) && strlen($data) > 0)) {
// Warning
echo "Warning: the file is empty or can't read contents\n";
echo $path."\n\n";
// Data ok
} else {
// Tag context
$do_preg_replace = true;
// Replace serialized string values
$data = preg_replace_callback('!s:(\d+):([\\\\]?"[\\\\]?"|[\\\\]?"((.*?)[^\\\\])[\\\\]?");!', function($m) {
if(empty($m[3])) return $m[0]; //dont change anything when no string has 0 chars
return 's:'.strlen(unescape_mysql($m[3])).':"'.unescape_quotes($m[3]).'";';
}, $data);
}
// Close file
fclose($fp);
// Check data
if (!(isset($data) && strlen($data) > 0)) {
// Check origin
if ($do_preg_replace) {
// Error
echo "Error: preg_replace returns nothing\n";
if (function_exists('preg_last_error')) echo "preg_last_error() = ".preg_last_error()."\n";
echo $path."\n\n";
}
// Data Ok
} else {
// And finally write data
if (!($fp = fopen($path, 'w'))) {
// Error
echo "Error: can't open input file for writing\n";
echo $path."\n\n";
// Open for write
} else {
// Write file data
if (!fwrite($fp, $data)) {
// Error
echo "Error: can't write input file\n";
echo $path."\n\n";
}
// Close file
fclose($fp);
}
}
}
}
}
?>