SiteDrive 1.0.4 corrupts Theme Builder layouts on import (JSON escape stripping) plus a silent data-loss risk in Cornerstone

Subject: SiteDrive 1.0.4 corrupts Theme Builder layouts on import (JSON escape stripping) — plus a silent data-loss risk in Cornerstone

Hi Themeco team,

I hit a reproducible bug in SiteDrive that silently corrupted 18 of 20 Theme Builder layouts when I migrated them between two of my sites. I’ve root-caused it and worked around it, but I wanted to report it because it will affect anyone using SiteDrive to distribute layouts — and there’s a second issue in Cornerstone that turns it into permanent data loss.

Environment

  • SiteDrive 1.0.4 (both sites)
  • Cornerstone 7.8.11 (source) / 7.8.12 (destination)
  • Pro theme with a pro-child child theme
  • PHP 8.3.31, LiteSpeed, WordPress current

The bug

SiteDrive strips one level of backslash escaping from a Theme Builder layout’s post_content during import.

Theme Builder layouts ( cs_layout_single , cs_layout_archive , etc.) store their entire element tree as raw JSON in wp_posts.post_content , unlike pages and global blocks which use the _cornerstone_data postmeta. On import, each layout’s post_content comes across with one backslash level removed.

That matters because it corrupts the JSON. Where the stored tree contains an escaped quote \" — which happens any time an element’s text content includes markup like <a href="..."> — the backslash is removed, the string terminates early, and json_decode() fails on the whole document.

Losses like \n to n and é to u00e9 also occur. Those don’t break parsing, but they silently corrupt the text content, so even layouts that still open are subtly damaged.

Evidence that it’s the import, not the source

  1. Every imported layout was smaller than its source , by 7 to 556 bytes, with the losses scattered throughout rather than truncated at the end. Each stripped backslash is exactly one lost byte.
  2. Escape census across 20 layouts (source vs imported):
  • \" present in 20/21 source layouts, only 5/20 after import
  • \n present in 16/21 source, 0/20 after import
  • \u present in 13/21 source, 1/20 after import — and that one was the destination site’s own native layout, which had never been imported
  1. A predictive test confirmed the mechanism. Backslash loss only breaks JSON when it removes a \" . Exactly one source layout contained no \" at all — and that was exactly the one and only import that still parsed. One for one.
  2. Re-importing reproduces it byte-identically. I re-imported one layout through the SiteDrive UI; the new copy had the same byte count and the same parse failure as the first. So this is deterministic, not a transient transfer glitch.

This looks like the classic WordPress slashing issue: wp_insert_post() and wp_update_post() call wp_unslash() internally, so callers must pass slashed data. Passing the raw JSON through strips one level. I’d suggest checking wherever the import path writes post_content for layout post types — a wp_slash() on the content before insert would likely fix it.

The second issue — this is the one that worries me

When json_decode() on a layout’s post_content fails, Cornerstone fails soft. It serves the editor an empty root document instead of surfacing an error. In the builder that appears as the normal “Get Started / Blank Canvas / Use Template / Clone Existing” screen with an empty Outline panel — visually identical to a brand-new empty layout.

There is nothing to distinguish “this layout is corrupt” from “this layout is empty.” So the natural user reaction is to assume the import didn’t take, open the layout, start rebuilding, and hit Save — which overwrites the corrupted but still-recoverable JSON with a genuinely empty document. At that point the original design is gone for good.

I came very close to doing exactly that. I’d suggest surfacing a parse failure explicitly — even a plain “this layout’s stored data could not be read” notice would prevent the destructive save.

What I did instead

For anyone who hits this before it’s fixed, the recovery path that worked was to bypass SiteDrive entirely: rebuild a .tco bundle from the source site’s layout data and import it through Cornerstone’s own cs_import_tco() , which handles slashing correctly. That restored all 19 layouts byte-for-byte identical to the source, including layout assignments, and regenerated the styles correctly.

Worth noting for your own reproduction: the damaged layouts could not be repaired in place, because any sane write path validates that the existing stored document parses first — and a corrupt one never will. The layouts had to be recreated.

What would help

  1. Confirmation of the slashing bug and whether a fixed SiteDrive release exists or is planned.
  2. Consideration of the fail-soft behavior above, given the data-loss exposure.
  3. If useful, I’m happy to provide the byte-level diffs, the escape census, or a corrupted layout export for your testing.

I’ll be repeating this migration pattern across a number of sites, so I’d rather use SiteDrive as intended than keep working around it.

Thanks,

Jeremy Bengtson The Search Sherpa

Hey Jeremy,

Yes, your analysis is 100% correct, and both of the concerns you raised looks like bugs.


Possible Bug 1: SiteDrive Post Import Slashing Issue (Confirmed Bug)

  • Why it happens:

    In includes/Providers/Post/Post.php, SiteDrive inserts the imported post data directly using:

    
    $postID = sitedrive_insert_post($postInsertData);
    
    

    Which wraps wp_insert_post():

    
    function sitedrive_insert_post($args) {
    
      $postID = wp_insert_post($args, true);
    
      // ...
    
    }
    
    

    As you correctly identified, wp_insert_post() expects slashed data because it runs wp_unslash() internally. Since SiteDrive passes the raw imported JSON inside post_content without slashing it first, WordPress strips one level of backslashes (converting \" to " and \\ to \), corrupting the layout JSON and failing any subsequent json_decode() parsing.

  • The Fix:

    Passing the post array through wp_slash() before calling sitedrive_insert_post($postInsertData) would resolve the issue.


Possible Bug 2: Cornerstone Fail-Soft Behavior (Confirmed Bug / Design Flaw)

  • Why it happens:

    When Cornerstone retrieves a layout, it attempts to decode the layout’s post_content JSON. If json_decode() fails (which happens when SiteDrive strips the escapes), Cornerstone’s parser catches or ignores the exception and falls back to returning a default empty root structure.

  • Why it is dangerous:

    As you pointed out, because the builder shows a clean, blank editor canvas with no warnings of a parse failure, users will assume the layout was successfully imported but empty. Saving this state causes Cornerstone to overwrite the corrupted but restorable JSON in the database with a clean, empty state, resulting in permanent data loss.

  • The Fix:

    Cornerstone should explicitly check if post_content is present but failed to parse, and block editor saves or show a prominent warning instead of serving an empty workspace.


Next Steps

Your workaround of using Cornerstone’s native .tco import via cs_import_tco() is the safest route to prevent backslash stripping and data loss until dev team investigation is done and updates are released.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.