From 4e204cbfb7831cb56088c81011793faf6a78dc30 Mon Sep 17 00:00:00 2001 From: Jamal Neufeld Date: Sat, 29 Mar 2014 22:04:50 -0400 Subject: [PATCH 1/2] Fixed bug with replacing url in serialized data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Background: The script first finds all serialized data and replaces the urls there, then it going through all the data and does a replace again, assuming the data in the serialized strings has been replaced. Problem: The script was using the javascript .replace() method using a standard string which only replaces the first occurrence of a url. Some data in the database has several occurrences though, so though it would properly change the length number on the serialized object, it would only replace one occurrence. The other occurrences would then be replaced by the regular find and replace which doesn’t update the length of the serialized object and therefore breaks that entire data object. So as an example, if you have two links in your widgets, which wordpress stores all in one serialized data object, you’ll break all your widgets because that whole data object is now corrupted. Solution: Instead of using the generic .replace(), we create a regex object based on the search key and use the /g flag which replaces all occurrences. Then we calculate the amount of occurrences of the url in that particular object and multiply the length_delta by that so we can properly change the length of the object. --- tasks/lib/util.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tasks/lib/util.js b/tasks/lib/util.js index b0d2887..04f89f2 100644 --- a/tasks/lib/util.js +++ b/tasks/lib/util.js @@ -100,9 +100,10 @@ exports.init = function (grunt) { exports.replace_urls_in_serialized = function(search, replace, string) { var length_delta = search.length - replace.length; + var searchRegExp = new RegExp(search, 'g'); // Replace for serialized data - var matches, length, delimiter, old_serialized_data, target_string, new_url; + var matches, length, delimiter, old_serialized_data, target_string, new_url, occurences; var regexp = /s:(\d+):([\\]*['"])(.*?)\2;/g; while (matches = regexp.exec(string)) { @@ -111,12 +112,13 @@ exports.init = function (grunt) { // If the string contains the url make the substitution if (target_string.indexOf(search) !== -1) { + occurences = target_string.match(searchRegExp).length; length = matches[1]; delimiter = matches[2]; // Replace the url - new_url = target_string.replace(search, replace); - length -= length_delta; + new_url = target_string.replace(searchRegExp, replace); + length -= length_delta * occurences; // Compose the new serialized data var new_serialized_data = 's:' + length + ':' + delimiter + new_url + delimiter + ';'; From 4958ceb6366ebc7cb328c8d88c9d699e85eef784 Mon Sep 17 00:00:00 2001 From: Jamal Neufeld Date: Sat, 7 Jun 2014 23:46:12 -0400 Subject: [PATCH 2/2] added test to replace_urls_in_serialized I added a test for replace_urls_in_serialized which tests multiple urls in a single serialized object --- test/deployments_test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/deployments_test.js b/test/deployments_test.js index 6bc6820..7307556 100644 --- a/test/deployments_test.js +++ b/test/deployments_test.js @@ -63,6 +63,13 @@ module.exports = { "Replace multiple urls into serialized data." ); + var string4 = '{s:19:"payment_success_url";s:74:"http://loremipsum/payment-successful/ and http://loremipsum/error-message/";s:16:"payment_fail_url";s:33:"http://loremipsum/payment-failed/";s:13:"currency_unit"}'; + test.equal( + util.replace_urls_in_serialized(search, replace, string4), + '{s:19:"payment_success_url";s:90:"http://www.loremipsum.com/payment-successful/ and http://www.loremipsum.com/error-message/";s:16:"payment_fail_url";s:41:"http://www.loremipsum.com/payment-failed/";s:13:"currency_unit"}', + "Replace multiple urls in a single serialized object into serialized data." + ); + test.done(); },