Skip to content

investigate 4-byte length prefix on Mac for Mac-XM* clipboard payloads #186

@fuzzzerd

Description

@fuzzzerd

Summary

SharpFM unconditionally prepends a 4-byte little-endian uint32 length header to the XML payload when writing to the clipboard, and unconditionally strips 4 bytes when reading. This matches FileMaker Pro's wire format on Windows (confirmed by Windows smoke testing, clips round-trip cleanly). macOS behavior is not yet validated and may differ — if FileMaker Pro on Mac does not use the prefix, SharpFM will currently corrupt round-trips on Mac in both directions.

Where the prefix lives

ClipboardService is a pure byte pipe. All prefix logic is in FileMakerClip:

  • Write (src/SharpFM.Model/FileMakerClip.cs:100-112):
    byte[] byteList = Encoding.UTF8.GetBytes(XmlData);
    byte[] intBytes = BitConverter.GetBytes(byteList.Length);
    _cachedRawData = intBytes.Concat(byteList).ToArray();
  • Read (src/SharpFM.Model/FileMakerClip.cs:62):
    XmlData = ClipBytesToPrettyXml(data.Skip(4));

Applied to every Mac-XM* format on every platform.

Failure modes if macOS doesn't use the prefix

  • Copy (SharpFM → FM on Mac): FileMaker reads 4 extra bytes before the XML — may reject the payload, render garbled, or silently truncate.
  • Paste (FM on Mac → SharpFM): SharpFM drops the first 4 bytes of real XML — the opening <fmxmlsnippet> is cut, XDocument.Parse fails or silently loses content.

What needs to happen

  1. Validate on macOS. Copy a script out of FileMaker Pro on Mac, paste into SharpFM, confirm the XML is intact (no trailing garbage, no truncated opening tag). Reverse: copy from SharpFM, paste into FileMaker Pro on Mac, confirm the script body imports cleanly.
  2. If round-trip fails, make the prefix handling platform-conditional:
    • FileMakerClip.cs:62data.Skip(OperatingSystem.IsWindows() ? 4 : 0)
    • FileMakerClip.cs:100-112 — prepend length only when OperatingSystem.IsWindows()
    • (Alternative: move the concern into ClipboardService so FileMakerClip stays a pure data model.)
  3. Add regression tests using a real Mac-captured payload fixture from step 1 so the platform split can't silently break later.

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions