)]}'
{
  "log": [
    {
      "commit": "91f6be17c3c0c427e902f4dafcbfe2733b794b06",
      "tree": "a639b7473bef7491006545d55b2d61d76c61ef66",
      "parents": [
        "b1a85ef9738016a1c4b00165a568e0d72ec4cc5d"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Aug 22 13:50:45 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Aug 22 13:50:45 2026 +0200"
      },
      "message": "Bump `commons-parent` to version 104\n"
    },
    {
      "commit": "b1a85ef9738016a1c4b00165a568e0d72ec4cc5d",
      "tree": "c96ccc94c5d523074687ffc058ea1b3c9b226abd",
      "parents": [
        "87eff6d475da424a5935515184f1b1ab5661411e",
        "0aeac4b21aa9c5cf9be1e05c37ea64ac02df151f"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Thu Aug 20 08:22:09 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 08:22:09 2026 -0400"
      },
      "message": "Merge pull request #41 from ppkarwasz/feature/harden-saxtransformerfactory\n\nHarden the SAXTransformerFactory extension surface"
    },
    {
      "commit": "87eff6d475da424a5935515184f1b1ab5661411e",
      "tree": "764b8b80f5b7a461c1e0a4f8cd8b2f8dbd50244e",
      "parents": [
        "125a1a3c5b1852a789d391ef135d13dbfe13fc3e",
        "27d80d8eeb4d80896feb90354c905be93b5369ee"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Thu Aug 20 08:20:22 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 08:20:22 2026 -0400"
      },
      "message": "Merge pull request #38 from ppkarwasz/docs/supported-runtime-floor\n\ndocs: document the supported-runtime floor (OpenJDK 8+)"
    },
    {
      "commit": "0aeac4b21aa9c5cf9be1e05c37ea64ac02df151f",
      "tree": "40806fa3b779104709712563568558ae8414a651",
      "parents": [
        "f45cbaffe6c76284c4e2910f7604ee4d8870864e"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Aug 19 14:28:34 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Aug 19 14:28:34 2026 +0200"
      },
      "message": "test: work around the Xalan/libexpat namespace-prefixes bug on Android in XMLFilterTest\n\nThe unconfigured XMLFilter controls built a plain Xalan filter and parsed\nwith no parent set, so Xalan\u0027s TrAXFilter self-provisioned a reader and\nenabled the namespace-prefixes feature on it. On Android that reader is\nlibexpat, which accepts the feature at setFeature time but fails mid-parse,\nso the Android instrumented run failed.\n\nOn Android the controls now hand the filter a permissive parent\n(AttackTestSupport.permissiveReader, wrapping the Expat reader to reject\nnamespace-prefixes eagerly like the production HardeningExpatXMLReader), so\nTrAXFilter uses it directly instead of self-provisioning. The\nexternal-general-entity control additionally skips on Android, whose Expat\ndoes not resolve the entity in this path, so there is no leak to demonstrate;\nits hardened counterpart still runs and must not leak. permissiveReader is\nfactored out of permissiveSaxSource, which keeps its behaviour.\n\nFull mvn matrix and the Android instrumented suite (connectedAndroidTest,\nPixel 6a API 33) green.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "27d80d8eeb4d80896feb90354c905be93b5369ee",
      "tree": "dd0ea5bf89f261550a4e9babe2b52be058bb43c3",
      "parents": [
        "4fd6c819a54329e1cd77a07a2df580d41d2913ca"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Aug 19 11:25:23 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Aug 19 11:32:39 2026 +0200"
      },
      "message": "docs: take Android out of the threat model\u0027s guarantee scope\n\nNo version of Android supports FEATURE_SECURE_PROCESSING (Android\u0027s own\nDocumentBuilderFactory.setFeature documentation says so explicitly), so the\nguarantees cannot be defined there at all, on any API level:\n\n- threat model: the guarantees are defined on the OpenJDK family only; Android\n  moves from an API-33 floor to out of scope on every API level, with a new\n  OUT-OF-SCOPE: unsupported runtime triage disposition. The in-scope recipe\n  list marks the Expat/KXmlParser recipes as best-effort.\n- index: Android remains a supported platform from API level 19, secured as\n  best-effort through the resolver floor; the hardening is tested as complete\n  starting with API level 33, and below that libexpat carries no\n  entity-expansion check. Android\u0027s XmlPullParser API is not supported, being\n  no JAXP API; parse untrusted XML through the hardened SAX or DOM factories.\n- XmlFactories javadoc: the guarantee paragraph now matches.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "f45cbaffe6c76284c4e2910f7604ee4d8870864e",
      "tree": "6679604a535787026cc68a1cab956fec9d3c302c",
      "parents": [
        "11c3740de8f7a5c59342ac848574543f5daa2bb2"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Aug 19 11:07:49 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Aug 19 11:07:49 2026 +0200"
      },
      "message": "fix: Javadoc\n"
    },
    {
      "commit": "11c3740de8f7a5c59342ac848574543f5daa2bb2",
      "tree": "60335e2fc64b2c799357352d45e1c37569d471ea",
      "parents": [
        "8bc0d82987cb95f696297ff97330d4eb56739876"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Aug 19 11:02:17 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Aug 19 11:02:17 2026 +0200"
      },
      "message": "fix: minor nitpicks\n"
    },
    {
      "commit": "8bc0d82987cb95f696297ff97330d4eb56739876",
      "tree": "516099ca1f3f07d498a05675317f418c535102c8",
      "parents": [
        "dec3ac0dfb9a499ecac72e5d9ac4391452672c09"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 23:31:07 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 23:31:07 2026 +0200"
      },
      "message": "docs: bring the SAXTransformerFactory extension surface into scope\n\nThe previous release documented the newTransformerHandler /\nnewTemplatesHandler / newXMLFilter surface as out of scope. Now that those\nproducts carry the resolver floor, flip the documentation to match:\n\n- threat model: the in-scope guarantee covers the extension methods when the\n  returned TransformerFactory exposes them; the out-of-scope bullet and the\n  Known non-findings bullet for that surface are removed.\n- index page: the \"Transformer handlers and filters\" note states the products\n  carry the same hardening as the standard entry points, and that the SAX\n  events fed into a handler and a caller-set filter parent remain caller\n  configuration.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "dec3ac0dfb9a499ecac72e5d9ac4391452672c09",
      "tree": "4f96d1e4ccce53b3bbb95f71202e7faea45554e2",
      "parents": [
        "94f041d34bad59ccb243962a5dd7d79c52a705e5"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 23:16:58 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 23:27:33 2026 +0200"
      },
      "message": "feat: harden the SAXTransformerFactory extension surface\n\nThe newTransformerHandler / newTemplatesHandler / newXMLFilter products of\nthe hardened TransformerFactory now carry the same resolver floor as the\nstandard entry points, addressing findings f003 and f004:\n\n- HardeningTransformerHandler wraps the handler and its LIVE transformer in\n  a HardeningTransformer, so runtime document() during the handler\u0027s\n  SAX-driven transform and through the getTransformer() bypass sits on the\n  floor (the stock JDK\u0027s newTransformerHandler(Templates) does not inherit\n  the factory resolver on its own).\n- HardeningTemplatesHandler returns a HardeningTemplates from getTemplates(),\n  so Transformers built from it carry the floor; include/import during the\n  feed already resolve through the factory floor in all implementations.\n- HardeningXMLFilter replaces the implementation filters, which\n  self-provision an unhardened input reader (the stock JDK\u0027s as early as\n  setContentHandler) and cast a supplied Templates to their own type. It\n  parses the input with a hardened parent reader installed on first parse\n  (a caller-set parent is trusted configuration) and transforms through a\n  HardeningTransformer.\n- newTransformerHandler(Templates) unwraps a HardeningTemplates before\n  delegating: implementations cast templates.newTransformer() to their own\n  Transformer type, so handing them the wrapper threw ClassCastException.\n\nSAXParserHardener gains newHardenedReader(), factored out of hardenSource.\nNew TransformerHandlerTest, TemplatesHandlerTest and XMLFilterTest cover the\nsurface on every TrAX execution, each with an unconfigured leak control;\nshade-footprint expectations grow by the three new wrapper classes.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "94f041d34bad59ccb243962a5dd7d79c52a705e5",
      "tree": "39700ee1d938d22650ba0b5eb7a37e41ee43b279",
      "parents": [
        "125a1a3c5b1852a789d391ef135d13dbfe13fc3e"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 21:54:54 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 23:26:43 2026 +0200"
      },
      "message": "refactor: wrap the Saxon TransformerFactory like every other implementation\n\nSaxon\u0027s TransformerFactory now goes through the same HardeningTransformerFactory\nwrapper as Xalan/XSLTC to get the FallbackIgnoreURIResolver floor, instead of a\nbespoke resolver floor inside its Configuration. The only difference is the\nempty-Source shape the floor returns for an unresolved reference: the default\nempty DOM document for other factories, EmptySource.getInstance() for Saxon,\nthreaded through as a Supplier\u003cSource\u003e from the factory down onto every produced\nTemplates and Transformer.\n\nSaxonProvider keeps only the vendor-specific Configuration bits JAXP cannot\nexpress (extension functions off, empty CollectionFinder, hardened makeParser,\n#DEFAULT parser classes), dropping the nature-aware IGNORE_ALL_FLOOR and the\nsetResourceResolver override. The XPath configure path, which has no factory\nwrapper, keeps a Configuration-level floor but reuses FallbackIgnoreURIResolver\n(adapted via Saxon\u0027s ResourceResolverWrappingURIResolver). Saxon class references\nstay confined to SaxonProvider, an optional dependency.\n\nUpdates the XPathHardener shade-footprint expectation to include the now-reachable\nFallbackIgnoreURIResolver. Full surefire matrix (test-saxon, test-saxon-xerces,\ntest-stockjdk, test-woodstox, test-xalan, test-xalan-xerces, test-xerces) green.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "125a1a3c5b1852a789d391ef135d13dbfe13fc3e",
      "tree": "29ee78969d74247716d96bfb9b083250ecd65abb",
      "parents": [
        "4d61f562ea5b1125e3ed103ba206eeb34f808053"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Aug 18 16:02:28 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Aug 18 16:02:28 2026 -0400"
      },
      "message": "Bump codeql-action from 4.37.6 to 4.37.7\n"
    },
    {
      "commit": "4d61f562ea5b1125e3ed103ba206eeb34f808053",
      "tree": "71786a6b15a384c0dc26e4dccda6416efadb703d",
      "parents": [
        "c7b774778e70c94b0ce0466365f82d25beac3a54",
        "1ce0ab7d4193a81f127edbfa65d9575ffab314ab"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Tue Aug 18 15:44:13 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 15:44:13 2026 -0400"
      },
      "message": "Merge pull request #40 from ppkarwasz/docs/saxtransformerfactory-out-of-scope\n\ndocs: declare the SAXTransformerFactory extension surface out of scope"
    },
    {
      "commit": "c7b774778e70c94b0ce0466365f82d25beac3a54",
      "tree": "7e9b56717f63330274869d0ef68a62f70dfc9a94",
      "parents": [
        "2a67b2f1fdb66f4980273f3197e5cfa62e76e407",
        "a9fc7b2f4e20fcbb13285626ee102753c9305c17"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Tue Aug 18 13:47:44 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 13:47:44 2026 -0400"
      },
      "message": "Merge pull request #39 from ppkarwasz/docs/fix-stale-harden-reference\n\ndocs: fix stale XmlFactories.harden(XMLReader) reference in threat model"
    },
    {
      "commit": "1ce0ab7d4193a81f127edbfa65d9575ffab314ab",
      "tree": "a73a224cca7416a0ef20c00929109a343808b72d",
      "parents": [
        "2a67b2f1fdb66f4980273f3197e5cfa62e76e407"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 19:46:25 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 19:46:25 2026 +0200"
      },
      "message": "docs: declare the SAXTransformerFactory extension surface out of scope\n\nThe factory returned by XmlFactories.newTransformerFactory() may be cast to\nSAXTransformerFactory, but its newTransformerHandler / newTemplatesHandler /\nnewXMLFilter methods, and the TransformerHandler, TemplatesHandler, Templates\nand XMLFilter objects they produce, are not hardened in this release.\n\nNarrows the previously unconditional \"every parser the factory creates\ninternally\" guarantee in the XmlFactories Javadoc to the standard\nTransformerFactory entry points, and records the exclusion in the threat model\n(What is in scope, What is out of scope, Known non-findings) and the index page.\nThe Javadoc no longer promises the runtime type of the returned factory.\n\nAddresses findings f003 (newXMLFilter) and f004 (handler products).\nDocumentation only; no behavior change.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "a9fc7b2f4e20fcbb13285626ee102753c9305c17",
      "tree": "7e9b56717f63330274869d0ef68a62f70dfc9a94",
      "parents": [
        "2a67b2f1fdb66f4980273f3197e5cfa62e76e407"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 19:27:07 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 19:27:07 2026 +0200"
      },
      "message": "docs: fix stale XmlFactories.harden(XMLReader) reference in threat model\n\nThe harden(XMLReader) and harden(Source) methods were removed from the public\nAPI of XmlFactories in #37. Update the \"Caller-supplied parser instances\"\nguidance to obtain a hardened reader from XmlFactories.newSAXParserFactory()\ninstead of the removed harden(XMLReader) method.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "4fd6c819a54329e1cd77a07a2df580d41d2913ca",
      "tree": "2e9732d329fe1f103cf501a8f65114a8c4587318",
      "parents": [
        "2a67b2f1fdb66f4980273f3197e5cfa62e76e407"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 19:22:49 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 19:22:49 2026 +0200"
      },
      "message": "docs: document the supported-runtime floor (OpenJDK 8+, Android 33+)\n\nState that the hardening guarantees are defined on OpenJDK 8 or later, or\nAndroid API level 33 or later. The bounded entity-expansion guarantee\n(Billion Laughs) relies on the platform\u0027s secure-processing limit, which on\nAndroid is libexpat\u0027s built-in check; that check first ships in API 33, so on\nAndroid below 33 the guarantee does not hold. Reports demonstrated only on an\nunsupported Android release are out of scope.\n\nQualifies the previously unconditional guarantee in the XmlFactories class\nJavadoc, the threat model (Assumptions about the environment, What is out of\nscope, Known non-findings, Conditions that would change this model), and the\nindex page. No behavior change.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "2a67b2f1fdb66f4980273f3197e5cfa62e76e407",
      "tree": "01b1822722ba6ccf60ca2a6427b39d89b1317d4c",
      "parents": [
        "9c84b10a3497940676db7b88533481679fc5d0a5"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 17:56:25 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 17:56:25 2026 +0200"
      },
      "message": "Remove the harden(XMLReader) and harden(Source) methods from the public API (#37)\n\nKeep the public surface of XmlFactories minimal for the first release:\ncallers who need a hardened XMLReader can obtain one from a hardened SAX\nfactory, and rewriting a Source is an edge case that can live in another\nlibrary. Both methods were one-line delegations to the package-private\nSAXParserHardener workhorses, which every internal caller already uses\ndirectly.\n\nJavadoc references now point at SAXParserHardener#hardenSource and\nSAXParserHardener#hardenReader, and the tests that exercised the\nhardened-in-place reader scenario (still relied on by SaxonProvider)\ncall the package-private hardenReader directly.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "9c84b10a3497940676db7b88533481679fc5d0a5",
      "tree": "245c2a600f8267610145c8249c6463178ca826e9",
      "parents": [
        "be0343d575dc4e1b20189425e4baa5b7aa62359c"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 17:08:20 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 17:08:20 2026 +0200"
      },
      "message": "fix: Restore hardened state after reset() (#36)\n\n* fix: Restore hardened state after SAXParser.reset()\n\nThe JAXP reset contract reverts a parser to its just-created state, which\ndiscards the reader-level configuration installed after creation, while the\nwrapper kept serving its stale cached views. HardeningSAXParser.reset() now\ndrops the cached reader and parser views, so the next getXMLReader() or\ngetParser() call runs the freshly reset reader through the hardening funnel\nagain, matching HardeningDocumentBuilder.reset().\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n\n* fix: Restore hardened state after Validator.reset()\n\nThe JAXP reset contract reverts a validator to its just-created state,\nwhich removes the resource-resolver floor installed by the constructor.\nHardeningValidator.reset() now re-establishes the bare floor, matching\nHardeningDocumentBuilder.reset().\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n\n* fix: Restore hardened state after Transformer.reset()\n\nThe JAXP reset contract reverts a transformer to its just-created state,\nand several implementations clear the URI resolver installed by the\nconstructor. HardeningTransformer.reset() now re-establishes the floor,\nseeded again with the factory\u0027s compile-time resolver, matching the other\nhardened wrappers.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n\n* test: Cover DocumentBuilder.reset()\n\nHardeningDocumentBuilder.reset() already re-establishes its floor, but no\ntest exercised it; a regression there would go unnoticed.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "be0343d575dc4e1b20189425e4baa5b7aa62359c",
      "tree": "93bf00c8e6e46485a5fb18e667dfad90ddd98e6d",
      "parents": [
        "a62d2fc93118c5bf666f537dbc316117ce4900b9",
        "4bcfdae02ebeda0142cc85ba3e3a0ac210c98ca8"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Tue Aug 18 06:09:51 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 06:09:51 2026 -0400"
      },
      "message": "Merge pull request #33 from ppkarwasz/chore/asf-yaml\n\nConfigure PR buttons"
    },
    {
      "commit": "a62d2fc93118c5bf666f537dbc316117ce4900b9",
      "tree": "37e559557c882973e018048777e4996b8334f6f6",
      "parents": [
        "33373046a30444a5131b1e3f031fe38ff579d0b1",
        "ea63d0366ecc9ce48ec68e81430a548eed41272d"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Tue Aug 18 06:09:15 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 06:09:15 2026 -0400"
      },
      "message": "Merge pull request #29 from apache/feature/threat-model-caller-supplied-parsers\n\n[docs] Treat caller-supplied parser instances as trusted configuration"
    },
    {
      "commit": "33373046a30444a5131b1e3f031fe38ff579d0b1",
      "tree": "d81235ae249ab1046701d0ec10da6765c025d6e9",
      "parents": [
        "6f1cdcaaf1843541322f8fee730f7a34cce87aa1",
        "cc78d16f8b85ed8268d657829501d1cfa47d84d0"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Tue Aug 18 06:08:11 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 18 06:08:11 2026 -0400"
      },
      "message": "Merge pull request #30 from apache/feature/ignore-all-resolver-floors\n\nCOMMONSXML-4: Make the resolver floors ignore-all with a throw-on-unresolved toggle\n"
    },
    {
      "commit": "cc78d16f8b85ed8268d657829501d1cfa47d84d0",
      "tree": "d81235ae249ab1046701d0ec10da6765c025d6e9",
      "parents": [
        "bc0fa180c05c56e4b31b9e5ae96f9c765cab66d3",
        "5c7688c19201824f89b1d49fc471d8984fa504fd"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 07:25:54 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 07:25:54 2026 +0200"
      },
      "message": "Merge branch \u0027feature/reduce-shade-footprint\u0027 into feature/ignore-all-resolver-floors\n"
    },
    {
      "commit": "5c7688c19201824f89b1d49fc471d8984fa504fd",
      "tree": "3c519cab86e968fb60b84a7d65803cb693f5472f",
      "parents": [
        "c0cbe709e7c8af2c6afab22d2347dcdc53ef0f63"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 07:24:38 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 07:24:38 2026 +0200"
      },
      "message": "fix: number of expected classes\n"
    },
    {
      "commit": "bc0fa180c05c56e4b31b9e5ae96f9c765cab66d3",
      "tree": "d81235ae249ab1046701d0ec10da6765c025d6e9",
      "parents": [
        "d962e4c6034c620e43a93c71f5c80c66d99a21b0",
        "c0cbe709e7c8af2c6afab22d2347dcdc53ef0f63"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 07:20:39 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 07:20:39 2026 +0200"
      },
      "message": "Merge branch \u0027feature/reduce-shade-footprint\u0027 into feature/ignore-all-resolver-floors\n"
    },
    {
      "commit": "c0cbe709e7c8af2c6afab22d2347dcdc53ef0f63",
      "tree": "2925bdd0d0f18bd4d269f169199c86304d385e67",
      "parents": [
        "0fcd0a1dbf9033d82a68a671901105428fa4e781",
        "6f1cdcaaf1843541322f8fee730f7a34cce87aa1"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 07:15:07 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Tue Aug 18 07:15:07 2026 +0200"
      },
      "message": "Merge remote-tracking branch \u0027apache/main\u0027 into feature/reduce-shade-footprint\n"
    },
    {
      "commit": "6f1cdcaaf1843541322f8fee730f7a34cce87aa1",
      "tree": "092699a21d792070a7329d4b35f231354fcca778",
      "parents": [
        "5f9a5b322c037db81ca809e8d5ca5b5210072c8b",
        "ff36786f4f603c21f699e4ef134a570a827051ad"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Mon Aug 17 20:15:41 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 17 20:15:41 2026 -0400"
      },
      "message": "Merge pull request #32 from apache/feature/schema-factory-language\n\nAdd a schemaLanguage parameter to XmlFactories.newSchemaFactory"
    },
    {
      "commit": "4bcfdae02ebeda0142cc85ba3e3a0ac210c98ca8",
      "tree": "264bfbed66d6baa6a9d9f8722eb9e36a7d67c9ed",
      "parents": [
        "5f9a5b322c037db81ca809e8d5ca5b5210072c8b"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Aug 13 08:28:50 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Aug 13 08:30:35 2026 +0200"
      },
      "message": "Configure PR buttons\n\nThis change:\n\n- enables the \"Update branch\" button, which updates the PR branch on top of the target branch,\n- deletes PR branches after the PR is merged,\n- keeps the \"Auto-merge\" button at its false default: without any required checks or reviews, this feature cannot be used.\n"
    },
    {
      "commit": "5f9a5b322c037db81ca809e8d5ca5b5210072c8b",
      "tree": "0e76c73c9160dbb25a51a4dbdfbf93e25a717cc9",
      "parents": [
        "e18cb498bc6d647532089c0f52a238618f7ec7e7"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Wed Aug 05 14:15:14 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Wed Aug 05 14:15:14 2026 -0400"
      },
      "message": "Bump actions/setup-java from 5.6.0 to 5.7.0\n"
    },
    {
      "commit": "e18cb498bc6d647532089c0f52a238618f7ec7e7",
      "tree": "e31d3b7ed84fd06609cc3f2c1e3f4d1bc3041fb9",
      "parents": [
        "441c008c9ad8e244c43c5509aab649c209fab9a3"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Aug 04 15:59:38 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Aug 04 15:59:38 2026 -0400"
      },
      "message": "Bump github/codeql-action from 4.37.3 to 4.37.6.\n"
    },
    {
      "commit": "ff36786f4f603c21f699e4ef134a570a827051ad",
      "tree": "f0445208c24fd52c279dac299a8128e5cfe61c45",
      "parents": [
        "70ab7d8ce4245c1ba19da246869146c948d8c182"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 21:27:21 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 21:27:21 2026 +0200"
      },
      "message": "Remove an unused import\n\nXMLConstants is no longer referenced from XmlFactories.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "d962e4c6034c620e43a93c71f5c80c66d99a21b0",
      "tree": "0f869bde5aec4d7573227bc448dc8f8de5c3346c",
      "parents": [
        "9278083497b6614c0fb23cc0d567812ebad3cddb"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 19:39:46 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Document the ignore-all contract on the site index\n\nAdd a Configuration section: external references resolve to empty\nstreams, applications that want rejection tighten the factory\nthemselves (a stricter feature or a throwing resolver, with no security\nweight either way), and org.apache.commons.xml.throwOnUnresolved is a\ntemporary debugging switch. Align the Usage paragraph with the same\ncontract.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "9278083497b6614c0fb23cc0d567812ebad3cddb",
      "tree": "31b5194a7b0ff0545a6c9467a1b92e98577ef00d",
      "parents": [
        "79d5e53b5903a48597db40623764cdd1c42353e9"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 14:56:50 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Reuse the forbidden message for rejected resolutions\n\nRestore HardeningException.forbidden with its five-part identifier\ntuple, now also naming the enabling property, in place of the\nsingle-argument unresolvedDenied helper the toggle had introduced. Each\nfloor passes the same identifiers the old deny floors did.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "79d5e53b5903a48597db40623764cdd1c42353e9",
      "tree": "5559ae299294274600b350ec5b0e0f101e370113",
      "parents": [
        "56ae5304cef4011fffc89b151427916a8ffdee12"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 14:36:02 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Add a toggle to reject unresolved external references\n\nSetting -Dorg.apache.commons.xml.throwOnUnresolved\u003dtrue switches every\nresolver floor from resolving an unresolved external reference to empty\ncontent to rejecting it with the resolution hook\u0027s exception. The\nproperty is read at resolution time, so it also applies to existing\nfactories, and references resolved by a caller-supplied resolver are\nunaffected. Requested by Gary in COMMONSXML-4.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "56ae5304cef4011fffc89b151427916a8ffdee12",
      "tree": "2c88fbe569a335ae749442fa3956c10217fd2c8e",
      "parents": [
        "ce9c4af6954325b9032b1be7123b5d7bda03ead6"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 10:46:21 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Drop the Woodstox undeclared-entity floor\n\nEmptying the external subset leaves any entity it declared undeclared,\nand Woodstox rejects such a reference unconditionally. The rejection\nkeeps the resource just as unfetched as the empty resolution the other\nimplementations produce, so the per-implementation hook is unnecessary;\na caller can still opt references in by setting the property, which\nlands their resolver behind a floor like every other resolver hook.\nExternalDtdTest\u0027s StAX case accepts the block accordingly.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "ce9c4af6954325b9032b1be7123b5d7bda03ead6",
      "tree": "aca8a3f1177c133a13473ac26027a146b13f4710",
      "parents": [
        "7ca43ba55db8b9599500e2009ddf19382ccd9524"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 10:46:12 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Name the external-entity tests after their assertions\n\nExternalGeneralEntityTest declares its entity in the internal subset,\nso nothing is ever undeclared and every surface asserts the strict\nno-leak outcome. ExternalParameterEntityTest is the one payload with a\ngenuinely undeclared entity after hardening, so all its surfaces assert\nthe dual blocks-or-does-not-leak contract, replacing the trax\nmessage-matching acceptance. Methods are renamed to state the assertion\nthey make.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "7ca43ba55db8b9599500e2009ddf19382ccd9524",
      "tree": "f9935c6bcfb4af90bc1a4e4232626ed7638e4c9c",
      "parents": [
        "42347e926baa948729a6fc2d0d9181cf5ab4e48e"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 10:11:22 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Judge blocked TrAX outcomes with a ThrowingConsumer\n\nKeep the pipeline strict and hand a thrown TransformerException to a\ncaller-supplied ThrowingConsumer that rethrows it (the default) or\nreturns to accept the block. This replaces the ErrorListener overloads\nand their swallowed-report tracking: with the strict listener installed\nthe factories throw at the first report, so the half-built Templates\npath never runs.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "42347e926baa948729a6fc2d0d9181cf5ab4e48e",
      "tree": "a8700efc7a875380bab1fe8545275a306bc66213",
      "parents": [
        "52194eb42c4cc46a23ee5cac0a710fe3dc6cb61c"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 09:18:58 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Tighten the TrAX leak assertions\n\nWith Saxon\u0027s protocol restrictor gone, the external-DTD and\nexternal-general-entity TrAX tests assert the strict no-leak outcome.\nThe parameter-entity tests stay strict through a caller-supplied error\nlistener that accepts only the JDK parser\u0027s \"referenced, but not\ndeclared\" report, which XML 1.0 section 4.1 demotes to an unreported\nvalidity constraint when the internal subset contains a parameter\nentity reference. Drop the now-unused blocks-or-does-not-leak Templates\nand Transformer helpers.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "52194eb42c4cc46a23ee5cac0a710fe3dc6cb61c",
      "tree": "20136f6f1eb2c20c891a1b3ce9ce69a3506804d9",
      "parents": [
        "673ea4a7b5d722dfe02c44ad594c40cd2d333b43"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 09:18:46 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Resolve ignored URIs to an empty document instead of an empty stream\n\nAn empty character stream is not a well-formed XML document, so XSLTC\nrejects it for document() and both XSLTC and Xalan reject an ignored\nxsl:include or xsl:import at compile time. A well-formed empty document\nlets every implementation proceed and evaluate to no content, so the\ninclude, import and document() tests now assert the strict no-leak\noutcome on all implementations.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "673ea4a7b5d722dfe02c44ad594c40cd2d333b43",
      "tree": "a3e79451394ccb6a13743a4e5ab89a90638b827a",
      "parents": [
        "49e22d538f23124aa4140a85ae38b7fa35ebf3bd"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 08:14:51 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Reuse the shared StAX capture helper in EntityResolverFloorTest\n\nFold CDATA capture into AttackTestSupport.captureStaxEventText, make it\npackage-private and drop the duplicate readStaxText.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "49e22d538f23124aa4140a85ae38b7fa35ebf3bd",
      "tree": "7324c6a3f080ff7e16bfa4ef57dfead3dc1e0f90",
      "parents": [
        "672780de8d60d253d43dc096cedb27ed231f975a"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 08:06:18 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Reuse the shared character-capture helpers in tests\n\nMake AttackTestSupport.captureCharacters package-private, add an\nInputSource overload and a capturingHandler factory, and replace the\neleven anonymous DefaultHandler copies in EntityResolverFloorTest and\nXIncludeTest with them.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "672780de8d60d253d43dc096cedb27ed231f975a",
      "tree": "53ec01de6cea958a96d0c274e4bf58d6c7ed44d5",
      "parents": [
        "61d3b23bfd176fcce1f745199dd8bf77146dcc76"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 08:05:56 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Tidy the HardenedConfiguration comments\n\nShorten the floor and constructor comments and install the floor through\nthe setResourceResolver override instead of calling super directly.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "61d3b23bfd176fcce1f745199dd8bf77146dcc76",
      "tree": "f5886011c6e7216cbf747765d152485f78c4b21b",
      "parents": [
        "848d55e2afbd2c309f2dee8c0ddde31aea66f69f"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Aug 01 22:30:21 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Extend the ignore-all floor to Saxon resource resolution\n\nSaxon was the odd one out: its ALLOWED_PROTOCOLS\u003d\"\" lockdown rejected\nevery unresolved external reference (for example an external DTD subset)\nwith an exception, where the other implementations resolve it to empty\ncontent through a floor.\n\nDrop the ALLOWED_PROTOCOLS setting and install a nature-aware ignore-all\nResourceResolver on the HardenedConfiguration instead:\n\n- XML, XSLT and XSD natures resolve to Saxon\u0027s EmptySource, so an\n  unresolved xsl:include/xsl:import compiles as an empty module and\n  doc()/document() return the empty sequence.\n- Text and binary natures resolve to an empty StreamSource, so\n  unparsed-text() yields the empty string.\n- External-entity and DTD natures return null so the lookup falls\n  through to the hardened reader\u0027s entity-resolver floor, keeping caller\n  allow-listing on the reader working.\n\nThe floor backs every resolution chain ahead of Saxon\u0027s direct-fetch\nfallback. A setResourceResolver override re-wraps any resolver installed\nlater (including through the plain-JAXP TransformerFactory.setURIResolver\nroute, which replaces the Configuration resolver wholesale) with the\nfloor as its fallback, and an empty CollectionFinder covers\nfn:collection, the one channel that bypasses the resource resolver.\n\nSaxon now passes the DOCTYPE-only and external-DTD suites like the other\nstacks; tests where implementations still diverge on unresolved\nxsl:import/include (XSLTC and Xalan reject the emptied module, Saxon\ncompiles it) accept either outcome and assert no leak. Pin the new\nnested class in ShadingFootprintTest.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "848d55e2afbd2c309f2dee8c0ddde31aea66f69f",
      "tree": "853c56743bbfc9c6e15a7a0dd254985a1dd10fd0",
      "parents": [
        "7ba03418d747d101aa0d0dbae866eb4b9385b2fc"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Aug 01 19:24:24 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Drop XERCES_LOAD_EXTERNAL_DTD from the hardening recipes\n\nWith the ignore-all floors as universal behavior, skipping the external\nDTD subset up front is redundant: when the parser requests it, the floor\nresolves it to empty content and the parse continues. Remove the feature\nfrom the DOM and SAX recipes together with the setOptionalFeature\nhelpers it was the only user of.\n\nActually requesting the subset exposed two gaps in the floors, fixed\nhere: both now echo the requested identifiers on the empty source they\nreturn (Xerces derives the entity\u0027s base URI from the system id and\nfails on null), and the LSResourceResolver floor hands its empty content\nover as a character stream, because the JDK\u0027s DOMEntityResolverWrapper\ndiscards empty string data.\n\nThe ignore outcome stays best-effort: Saxon\u0027s ALLOWED_PROTOCOLS\nrestrictor sits ahead of the floor and rejects the subset lookup\noutright, so the affected TrAX tests accept either outcome through the\nassert*BlocksOrDoesNotLeak helpers and DoctypeOnlyTest documents the\ndual outcome.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "7ba03418d747d101aa0d0dbae866eb4b9385b2fc",
      "tree": "0fd287e32d96f402211a420242cad01c4b968eb9",
      "parents": [
        "0fcd0a1dbf9033d82a68a671901105428fa4e781"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Jul 11 14:14:56 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:59 2026 -0400"
      },
      "message": "Make the resolver floors ignore-all instead of deny-all\n\nAn external reference the caller\u0027s resolver does not resolve is now resolved\nto empty content rather than rejected with an exception. Nothing is fetched\neither way, so the security property is unchanged; the difference is that a\nparse now continues with empty content instead of failing.\n\nRename the four floors accordingly and collapse the variants the deny/ignore\nsplit required:\n\n  FallbackDenyEntityResolver2    -\u003e FallbackIgnoreEntityResolver2\n  FallbackDenyXMLResolver        -\u003e FallbackIgnoreXMLResolver\n  FallbackDenyLSResourceResolver -\u003e FallbackIgnoreLSResourceResolver\n  FallbackDenyURIResolver        -\u003e FallbackIgnoreURIResolver\n\n`SAXParserHardener.DtdAwareDenyResolver` and `StaxHardener.DtdSubsetFloor`\nexisted only to exempt the external DTD subset from the deny, and the old\n`FallbackIgnoreXMLResolver` only to exempt Woodstox\u0027s undeclared entities;\nwith ignore as the default all three are redundant. Removing them, together\nwith the now-dead `HardeningException.forbidden`, takes the shade closure from\n33 classes to 30.\n\nStAX collapses further: the floor moves into the `HardeningXMLInputFactory`\nconstructor (as `HardeningXMLReader` already did), a single `setXMLResolver`\ncovers both the JDK Zephyr and Woodstox (whose `setXMLResolver` fans out to\nits DTD-subset and entity resolvers), and the Zephyr `ignore-external-dtd`\nproperty is dropped because the floor already empties the subset. Only\nWoodstox\u0027s undeclared-entity hook stays separate: emptying the external subset\nleaves the entities it declared undeclared, and that hook is outside the\nfan-out.\n\nTests that asserted an exception now assert the external resource does not\nleak. Where the outcome differs by implementation (Saxon still rejects through\nALLOWED_PROTOCOLS, an emptied schema import fails to compile) they accept\neither outcome through the new assert*BlocksOrDoesNotLeak helpers.\n\nAssisted-By: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "0fcd0a1dbf9033d82a68a671901105428fa4e781",
      "tree": "ca6af837cdd13e53b0ba7724483b27b8322903ad",
      "parents": [
        "6a547ef78339b4e1a9011c5e63c7c657690dd0f2"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Aug 01 17:48:08 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:58 2026 -0400"
      },
      "message": "Disable ShadingFootprintTest in a native image\n\nThe test reads the compiled .class files from the code-source location,\nwhich only exists on a regular JVM: a native image carries no bytecode\n(and nobody shades one), so every closure lookup fails there. Disable it\nwith @DisabledInNativeImage, matching its exclusion from the Android\ntest compile.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "6a547ef78339b4e1a9011c5e63c7c657690dd0f2",
      "tree": "13f59dde84f175cd980f51091a3591dbb3cf06be",
      "parents": [
        "4c59616daa6a5a79cc3ad947102a97f903cfae13"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Aug 01 17:10:41 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:58 2026 -0400"
      },
      "message": "Add SchemaHardener as the schema entry point\n\nGive schema validation the same shape as the other JAXP types: a\ndedicated hardener class that XmlFactories delegates to, instead of\nnewSchemaFactory wrapping HardeningSchemaFactory directly. The class\nstays package-private like the other hardeners; it will back a public\nentry point if the hardeners are exposed later.\n\nPin SchemaHardener as the schema entry point in ShadingFootprintTest.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "4c59616daa6a5a79cc3ad947102a97f903cfae13",
      "tree": "2006607d2fb6d432b055920e0ee13c02c86cac2e",
      "parents": [
        "5bb6e893b293f9d7e6717e4b932af9cfc784f13f"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Jul 08 11:07:49 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:58 2026 -0400"
      },
      "message": "Break the XmlFactories cycle for TrAX, XPath and schema\n\nThe TrAX, schema and Saxon wrappers re-harden their sub-parsers by\ncalling XmlFactories.harden(Source/XMLReader); because those helpers live\non XmlFactories, whose class also news up every hardener, referencing\nthem dragged the whole library into each of those shade closures.\n\nMove harden(Source)\u0027s body to package-private SAXParserHardener.\nhardenSource (it needs only the SAX path) and repoint the internal\ncallers: the four Source callers to hardenSource, SaxonProvider to\nSAXParserHardener.hardenReader. The public XmlFactories.harden(Source)/\nharden(XMLReader) stay as thin delegates, so the API is unchanged, but no\nhardener transitively reaches XmlFactories anymore.\n\nEach heavy entry point now pulls only its own wrappers, its floor and the\nshared SAX path:\n\n- TransformerHardener:    32 -\u003e 17 classes, 75204 -\u003e 37366 bytes\n- XPathHardener:          32 -\u003e 13 classes, 75204 -\u003e 26471 bytes\n- HardeningSchemaFactory: 32 -\u003e 13 classes, 75204 -\u003e 32763 bytes\n\nPin the three closures in ShadingFootprintTest and assert only the public\nXmlFactories entry still pulls all 32 classes.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "5bb6e893b293f9d7e6717e4b932af9cfc784f13f",
      "tree": "33a912581af077c7c3253860fd97cbd9b3195ba4",
      "parents": [
        "b5267e15ec812488fca510efd6c4630597faafea"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Jul 08 10:52:46 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:58 2026 -0400"
      },
      "message": "Split the resolver floors into top-level classes\n\nPromote the five nested Resolvers.Fallback* floors to top-level,\npackage-private classes and delete the Resolvers container. The floors\nwere bound together only by the shared forbiddenMessage, now on\nHardeningException (Phase 1), and by being nested in one class, which\nmaven-shade minimizeJar keeps together. Splitting them means shading one\nhardener pulls only the floor(s) it uses:\n\n- DocumentBuilderHardener: 10 -\u003e 5 classes, 19265 -\u003e 12161 bytes\n- SAXParserHardener:       13 -\u003e 8 classes, 25721 -\u003e 18242 bytes\n- StaxHardener:            10 -\u003e 6 classes, 20547 -\u003e 13433 bytes\n\nThe EntityResolver2 floor is named FallbackDenyEntityResolver2; it also\ncarries the shared \"floor\" overview the container used to hold. Update\nShadingFootprintTest\u0027s expected sets and exclude that JVM-only test\n(jdependency) from the Android test compile.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "b5267e15ec812488fca510efd6c4630597faafea",
      "tree": "65fca8d9b15bdde28c612aa449e0328169cb0da8",
      "parents": [
        "13e0b748bf7a25b1b9b113804a3bd3af199d8a3b"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Jul 08 10:29:43 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:58 2026 -0400"
      },
      "message": "Inline the typed JAXP setters into each hardener\n\nMove the setFeature/setOptionalFeature/trySetProperty/trySetAttribute/\nsetOptionalAttribute helpers out of the shared JaxpSetters class and into\nthe hardener that uses them, as private methods, so shading one hardener\nno longer drags in the setters (and dead overloads) of the others. Only\nthe shared \"Failed to set ...\" message stays central, on\nHardeningException.settingFailed. Delete JaxpSetters.\n\nCuts the DOM/SAX/StAX shade closures by the whole JaxpSetters class\n(7946 bytes): DocumentBuilderHardener 26225 -\u003e 19265, SAXParserHardener\n32508 -\u003e 25721, StaxHardener 28173 -\u003e 20547 bytes. Update\nShadingFootprintTest\u0027s expected sets accordingly.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "13e0b748bf7a25b1b9b113804a3bd3af199d8a3b",
      "tree": "5e02fe42cb6bbf83e5f55e5c687821b1c0a09b66",
      "parents": [
        "441c008c9ad8e244c43c5509aab649c209fab9a3"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Jul 08 10:22:21 2026 +0200"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sun Aug 02 15:15:58 2026 -0400"
      },
      "message": "Centralize hardening messages on HardeningException\n\nAdd two static helpers to HardeningException so every hardener and every\nresolver floor shares one message format:\n\n- settingFailed(kind, name, target, cause) replaces JaxpSetters\u0027 inline\n  \"Failed to set ...\" construction.\n- forbidden(...) replaces the private Resolvers.forbiddenMessage, so the\n  five floors no longer route their message through the outer Resolvers\n  class.\n\nBehavior-preserving: the messages are byte-identical. This is the shared\ncore for the per-hardener shade-footprint reduction that follows.\n\nAdd ShadingFootprintTest, which uses jdependency (the library maven-shade\nminimizeJar uses) to pin each hardener entry point\u0027s transitive class\nclosure and print its size as a share of the full library, so later\nphases can show the footprint shrinking.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "70ab7d8ce4245c1ba19da246869146c948d8c182",
      "tree": "0c1a1a36fb114010d7b9b4f50a71819312a75ebe",
      "parents": [
        "26638d7f8e3f4153a4dfdb2d7690a27402e0df73"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 21:10:23 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 21:10:23 2026 +0200"
      },
      "message": "fix: Javadoc\n"
    },
    {
      "commit": "26638d7f8e3f4153a4dfdb2d7690a27402e0df73",
      "tree": "50afbd2d0f50a6ba50b7c3d3fc032c448e97d669",
      "parents": [
        "e51431f9303efc1e0da752a0825c43e003afd66c"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 20:30:42 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Aug 02 20:30:42 2026 +0200"
      },
      "message": "Add a schemaLanguage parameter to newSchemaFactory\n\nMirror SchemaFactory.newInstance(String): the caller picks the schema\nlanguage instead of the method hardcoding W3C XML Schema. The hardening\nis enforced through the LSResourceResolver hook and hardened source\nrewriting rather than any implementation-specific setting, so it holds\nfor whichever schema language JAXP locates a factory for.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "441c008c9ad8e244c43c5509aab649c209fab9a3",
      "tree": "3b8506679b9279f8486dc3fe1cae8789561f59fe",
      "parents": [
        "0dd96ba87be1a2e3bda57bc5451b98aeb591f613"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Aug 01 14:47:18 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Aug 01 14:47:18 2026 -0400"
      },
      "message": "Make package private class SaxonProviderConfigurer final\n"
    },
    {
      "commit": "0dd96ba87be1a2e3bda57bc5451b98aeb591f613",
      "tree": "6c490137d55104482ae00cf66f9a70925ef10729",
      "parents": [
        "e51431f9303efc1e0da752a0825c43e003afd66c"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Aug 01 14:47:04 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Aug 01 14:47:04 2026 -0400"
      },
      "message": "Make package private class HardeningException final\n"
    },
    {
      "commit": "ea63d0366ecc9ce48ec68e81430a548eed41272d",
      "tree": "88493eb9897a3da5e08e480798d8b46522b5eed0",
      "parents": [
        "e51431f9303efc1e0da752a0825c43e003afd66c"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Aug 01 18:27:16 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sat Aug 01 18:33:35 2026 +0200"
      },
      "message": "Treat caller-supplied parser instances as trusted configuration\n\nA recurring report shape builds its own permissively configured\nXMLReader, wraps it in a SAXSource, and reports the resulting entity\nresolution against the library. The code already takes a position on\nthis (a SAXSource carrying its own XMLReader is trusted as-is), but the\nthreat model never said it, so such a report could only land in\nMODEL-GAP.\n\nState it in the model: parser objects the caller constructs outside the\nlibrary (XMLReader in a SAXSource, StAX readers in a StAXSource, a\npre-parsed DOMSource) sit on the trusted side of the boundary, like the\nfactory configuration. Add the matching out-of-scope bullet with the\nsafe alternative (route your reader through XmlFactories.harden), a\nknown non-finding describing the report shape, and widen the caller\ninput disposition to cover it.\n\nAssisted-By: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "e51431f9303efc1e0da752a0825c43e003afd66c",
      "tree": "90d4d31d8174d2b8f4ead0089ddda28d452740d5",
      "parents": [
        "6d3234a0c311ab491523dadac58c080ecd23c7f7",
        "0884ea8ed372aa2a36eb64903af1a9a621dea61b"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Sat Aug 01 07:36:05 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 01 07:36:05 2026 -0400"
      },
      "message": "Merge pull request #24 from apache/feature/ci-matrix-platforms\n\n[COMMONSXML-11] Restructure the build matrix around the axes that matter\n"
    },
    {
      "commit": "6d3234a0c311ab491523dadac58c080ecd23c7f7",
      "tree": "07e874550a17ed168bcd7f58f067f87f05a9b18b",
      "parents": [
        "0e21e081704d173e700b5f4e91f040df4d1fc07c",
        "2863b29040685dce06c9a44ab115fee35f060e33"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Sat Aug 01 07:09:15 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 01 07:09:15 2026 -0400"
      },
      "message": "Merge pull request #23 from apache/feature/ci-matrix\n\nRun the test suite as a GraalVM native image\n"
    },
    {
      "commit": "0e21e081704d173e700b5f4e91f040df4d1fc07c",
      "tree": "871321bb19654f7dcfe395ca6ca17748b6f58a38",
      "parents": [
        "a00db730ede0a6fa4ce7e3d702eefe238841ca39",
        "d7e426296cbcb66308f90e349b81d8c1beb0191d"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sat Aug 01 07:03:26 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 01 07:03:26 2026 -0400"
      },
      "message": "Merge pull request #22 from ppkarwasz/feature/remove-limits-class\n\n[COMMONSXML-2] Remove `Limits` class and related functionality"
    },
    {
      "commit": "0884ea8ed372aa2a36eb64903af1a9a621dea61b",
      "tree": "21970f189348ee12866a810a25e02bc63fb04329",
      "parents": [
        "b184cd64865d6e111b29d2fd73083a682b0cbe89",
        "2863b29040685dce06c9a44ab115fee35f060e33"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 31 21:55:01 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 31 21:55:01 2026 +0200"
      },
      "message": "Merge branch \u0027feature/ci-matrix\u0027 into feature/ci-matrix-platforms\n"
    },
    {
      "commit": "d7e426296cbcb66308f90e349b81d8c1beb0191d",
      "tree": "871321bb19654f7dcfe395ca6ca17748b6f58a38",
      "parents": [
        "02005a20826492574ef47618b32880ce6ed19bde",
        "a00db730ede0a6fa4ce7e3d702eefe238841ca39"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 31 21:49:16 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 31 21:49:16 2026 +0200"
      },
      "message": "Merge remote-tracking branch \u0027apache/main\u0027 into feature/remove-limits-class\n\n# Conflicts:\n#\tsrc/main/java/org/apache/commons/xml/Limits.java\n"
    },
    {
      "commit": "2863b29040685dce06c9a44ab115fee35f060e33",
      "tree": "4b1aaba773704dfda123db2f89ceea68d327522b",
      "parents": [
        "bc08dcb618dc886ff0c10d557b2a4bd1cbd7f920"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:35:52 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Fri Jul 31 21:47:08 2026 +0200"
      },
      "message": "fix: add `|| false` to `continue-on-error`\n"
    },
    {
      "commit": "bc08dcb618dc886ff0c10d557b2a4bd1cbd7f920",
      "tree": "73c47ab8d1febc3a5737efb4125f8d0eb79b2126",
      "parents": [
        "8bc56f253ba450f63a8492cee1f84062bfe77aa0"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:20:58 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Fri Jul 31 21:47:08 2026 +0200"
      },
      "message": "fix: make GraalVM experimental\n"
    },
    {
      "commit": "8bc56f253ba450f63a8492cee1f84062bfe77aa0",
      "tree": "7d00186ec9cfd896b3e261d0273cd198173a3026",
      "parents": [
        "b6eebc9b98775eb1be07c207998d8af4b44ea167"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 22:33:23 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Fri Jul 31 21:47:08 2026 +0200"
      },
      "message": "Fix POM comment\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "b6eebc9b98775eb1be07c207998d8af4b44ea167",
      "tree": "00df843b51fea0892e2f3bbd82e8d9a8d4f8e854",
      "parents": [
        "a00db730ede0a6fa4ce7e3d702eefe238841ca39"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 22:04:32 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Fri Jul 31 21:47:08 2026 +0200"
      },
      "message": "Run the test suite as a GraalVM native image\n\nAdd a `native-xalan` profile that builds the tests into a native image, and\na GraalVM job to the CI matrix that activates it. This exercises a code path\nthe JVM matrix cannot reach: native-image resolves the JAXP providers at\nbuild time under the closed-world assumption, rather than at run time\nthrough ServiceLoader.\n\nA native binary carries one classpath, so only `test-stockjdk` runs; the\nother JAXP combinations stay on the JVM matrix. Saxon-HE is dropped, since\nits JAXP entry points carry no reachability metadata and every ServiceLoader\nlookup would fail on a missing no-arg constructor. Its `xpath3` group is\nalready excluded from that execution.\n\nApache Xalan supplies TrAX. The stock JDK\u0027s XSLTC compiles each stylesheet\ninto translet bytecode and defines the class at run time, which a\nclosed-world image cannot do: with XSLTC the transform tests fail on `No\nclasses have been predefined during the image build`. Predefining them does\nnot help either, even though JDK-8274535 made the generated bytecode\ndeterministic; the image builder rejects the class with `Cannot define class\ndie.verwandlung.fixture`. Interpretive Xalan, the workaround named on that\nsame issue, needs no bytecode at run time. Xalan and its serializer are\ndeclared as project dependencies rather than through surefire\u0027s\nadditionalClasspathDependencies, which native-image never sees.\n\nReachability metadata comes from the tracing agent rather than a committed\nconfig: Xalan reflects on its template setters and reads serializer defaults\nfrom property files, none of which static analysis sees, and a hand-written\nconfig would rot against every Xalan and JDK update. The attack fixtures are\nembedded explicitly, since the agent records only the resources a given run\nhappened to open.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "a00db730ede0a6fa4ce7e3d702eefe238841ca39",
      "tree": "fc10fb16afbde279c6b2a79a994a61ce9f34682b",
      "parents": [
        "4e5895fc1a4ecd2443fa419d62d5c3cb58a276c1"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Wed Jul 29 08:15:04 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Wed Jul 29 08:15:04 2026 -0400"
      },
      "message": "Bump ossf/scorecard-action from 2.4.3 to 2.4.4.\n"
    },
    {
      "commit": "4e5895fc1a4ecd2443fa419d62d5c3cb58a276c1",
      "tree": "01566d6e8b46ece7dab618cac7e565913c197877",
      "parents": [
        "e0d665d7de82ca0ab0d326605687159c5c495709"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Jul 28 14:54:57 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Jul 28 14:54:57 2026 -0400"
      },
      "message": "Bump github/codeql-action from 4.37.1 to 4.37.3\n"
    },
    {
      "commit": "e0d665d7de82ca0ab0d326605687159c5c495709",
      "tree": "4c585888c3c1212ec12aa629ac685cf735be926a",
      "parents": [
        "d3c3bb6cb6b02b894e734c0f8a981c5979aac0a1",
        "47491aacbb98aa769954fb1a48dc00f05faa05fe"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 25 12:11:10 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 25 12:11:10 2026 -0400"
      },
      "message": "Merge branch \u0027main\u0027 of https://github.com/apache/commons-xml into main"
    },
    {
      "commit": "d3c3bb6cb6b02b894e734c0f8a981c5979aac0a1",
      "tree": "45f1cde59b1518100f5f31b18c54b962e76c6aa6",
      "parents": [
        "a4630c738ee9da23cd405a338a4e37d1c065535e"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 25 09:50:21 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 25 09:50:21 2026 -0400"
      },
      "message": "Bump actions/checkout from 7.0.0 to 7.0.1\n"
    },
    {
      "commit": "47491aacbb98aa769954fb1a48dc00f05faa05fe",
      "tree": "4c585888c3c1212ec12aa629ac685cf735be926a",
      "parents": [
        "a4630c738ee9da23cd405a338a4e37d1c065535e",
        "dc79fdcb54e48c4efdb340c4f3df689021390b19"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Sat Jul 25 09:37:54 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 25 09:37:54 2026 -0400"
      },
      "message": "Merge pull request #26 from apache/dependabot/github_actions/actions/checkout-7.0.1\n\nbuild(deps): bump actions/checkout from 7.0.0 to 7.0.1"
    },
    {
      "commit": "dc79fdcb54e48c4efdb340c4f3df689021390b19",
      "tree": "4c585888c3c1212ec12aa629ac685cf735be926a",
      "parents": [
        "a4630c738ee9da23cd405a338a4e37d1c065535e"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sat Jul 25 13:32:51 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 25 13:32:51 2026 +0000"
      },
      "message": "build(deps): bump actions/checkout from 7.0.0 to 7.0.1\n\nBumps [actions/checkout](https://github.com/actions/checkout) from 7.0.0 to 7.0.1.\n- [Release notes](https://github.com/actions/checkout/releases)\n- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1)\n\n---\nupdated-dependencies:\n- dependency-name: actions/checkout\n  dependency-version: 7.0.1\n  dependency-type: direct:production\n  update-type: version-update:semver-patch\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e"
    },
    {
      "commit": "a4630c738ee9da23cd405a338a4e37d1c065535e",
      "tree": "a0e6d7498ef432e271b5e882b0ed9846ec6bd61c",
      "parents": [
        "91897e3305a83c67820203f49a476ff9cff1b955"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sat Jul 25 12:55:21 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jul 25 12:55:21 2026 +0200"
      },
      "message": "build(deps): bump reactivecircus/android-emulator-runner (#25)\n\nBumps [reactivecircus/android-emulator-runner](https://github.com/reactivecircus/android-emulator-runner) from 2.37.0 to 2.38.0.\n- [Release notes](https://github.com/reactivecircus/android-emulator-runner/releases)\n- [Changelog](https://github.com/ReactiveCircus/android-emulator-runner/blob/main/CHANGELOG.md)\n- [Commits](https://github.com/reactivecircus/android-emulator-runner/compare/e89f39f1abbbd05b1113a29cf4db69e7540cae5a...a421e43855164a8197daf9d8d40fe71c6996bb0d)\n\n---\nupdated-dependencies:\n- dependency-name: reactivecircus/android-emulator-runner\n  dependency-version: 2.38.0\n  dependency-type: direct:production\n  update-type: version-update:semver-minor\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "91897e3305a83c67820203f49a476ff9cff1b955",
      "tree": "b416c07e220084f67137aada66b8c1006326b545",
      "parents": [
        "24f22a105212fd1776ee1c48228cdec0880ca07c"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Wed Jul 22 09:44:48 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Wed Jul 22 09:44:48 2026 -0400"
      },
      "message": "Bump org.apache.commons:commons-parent from 102 to 103.\n"
    },
    {
      "commit": "24f22a105212fd1776ee1c48228cdec0880ca07c",
      "tree": "24b36316ccd9f8432bde96da416a09e002fa34c4",
      "parents": [
        "544badda4fefe459f23a4d8d8f49b3a3de4e30e1"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Jul 21 13:46:19 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Jul 21 13:46:19 2026 -0400"
      },
      "message": "Bump github/codeql-action from 4.37.0 to 4.37.1\n"
    },
    {
      "commit": "544badda4fefe459f23a4d8d8f49b3a3de4e30e1",
      "tree": "df126bb7cb32233016b02e61d154d3c4a596a740",
      "parents": [
        "2647cf2011f81d70cb0c6ce9074ef5ded6cd10b3"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Jul 21 11:46:36 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Tue Jul 21 11:46:36 2026 -0400"
      },
      "message": "Bump actions/setup-java from 5.5.0 to 5.6.0\n"
    },
    {
      "commit": "2647cf2011f81d70cb0c6ce9074ef5ded6cd10b3",
      "tree": "ca210780229884ace0f23b0a646ffcbb3d642609",
      "parents": [
        "d075b53e85d73e7fb9db7ae6d8fc17bab8ac295e"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Mon Jul 13 13:50:35 2026 -0700"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Mon Jul 13 13:50:35 2026 -0700"
      },
      "message": "Bump actions/setup-java from 5.4.0 to 5.5.0\n"
    },
    {
      "commit": "d075b53e85d73e7fb9db7ae6d8fc17bab8ac295e",
      "tree": "3b22a2fc474170ee6bb1c906bb6ba535fdbe1e67",
      "parents": [
        "2d638e101f3436b5ffe1518b62abb586f7642cab"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 11 11:22:58 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 11 11:22:58 2026 -0400"
      },
      "message": "Javadoc\n"
    },
    {
      "commit": "2d638e101f3436b5ffe1518b62abb586f7642cab",
      "tree": "9e4a44d41cc85a3f734a96cbe06e7e6d56026130",
      "parents": [
        "117f1e44121d1e8cd7a9cb10c08eff63c1197b2a"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 11 09:09:24 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 11 09:09:24 2026 -0400"
      },
      "message": "Javadoc\n"
    },
    {
      "commit": "117f1e44121d1e8cd7a9cb10c08eff63c1197b2a",
      "tree": "0ce83b12afd043882b7b0bbff00e4f6f8f26afdc",
      "parents": [
        "737180a3c674c4ca3736541b6ca487858ecbe07a"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 11 08:48:29 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Sat Jul 11 08:48:29 2026 -0400"
      },
      "message": "Javadoc\n"
    },
    {
      "commit": "b184cd64865d6e111b29d2fd73083a682b0cbe89",
      "tree": "6a6882452c4b9c0806d5baa150ac46328e29d722",
      "parents": [
        "1073f82705a4685afb620f5de9691c722a0c3c1f",
        "72020370ce5283885b93963ac4eeb71785ae4269"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 23:28:12 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 23:28:12 2026 +0200"
      },
      "message": "Merge branch \u0027feature/ci-matrix\u0027 into feature/ci-matrix-platforms\n"
    },
    {
      "commit": "1073f82705a4685afb620f5de9691c722a0c3c1f",
      "tree": "6a6882452c4b9c0806d5baa150ac46328e29d722",
      "parents": [
        "caa0d3b07e7da4351a97e535b7977a3b6e8b4218",
        "737180a3c674c4ca3736541b6ca487858ecbe07a"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 23:27:23 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 23:27:23 2026 +0200"
      },
      "message": "Merge remote-tracking branch \u0027apache/main\u0027 into feature/ci-matrix-platforms\n"
    },
    {
      "commit": "72020370ce5283885b93963ac4eeb71785ae4269",
      "tree": "3dfc44d09b7e9e8eb16bcfffe73ab3cad3f36b60",
      "parents": [
        "11694688b274c83a60c6c8ae46f197629fa1fb40",
        "737180a3c674c4ca3736541b6ca487858ecbe07a"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 23:27:05 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 23:27:05 2026 +0200"
      },
      "message": "Merge remote-tracking branch \u0027apache/main\u0027 into feature/ci-matrix\n"
    },
    {
      "commit": "02005a20826492574ef47618b32880ce6ed19bde",
      "tree": "d33818bdc8bb3d9adfbf01f6afee6f097787d3d3",
      "parents": [
        "55b9b13379b184cc9568a1c70a2bf27f875b734a",
        "737180a3c674c4ca3736541b6ca487858ecbe07a"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 23:17:57 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 23:17:57 2026 +0200"
      },
      "message": "Merge remote-tracking branch \u0027apache/main\u0027 into feature/remove-limits-class\n"
    },
    {
      "commit": "737180a3c674c4ca3736541b6ca487858ecbe07a",
      "tree": "8fbab7b5ef954e27f3ba56c71aa1ea6acef9758a",
      "parents": [
        "b2cc824abbdce65f2aa1edf94cd22fba3580c610",
        "ecda422e59027f8243f7eed4796b63c3c59ba783"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@users.noreply.github.com",
        "time": "Fri Jul 10 16:04:32 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jul 10 16:04:32 2026 -0400"
      },
      "message": "Merge pull request #21 from ppkarwasz/fix/xinclude\n\n[COMMONSXML-10] Block XInclude (xi:include) href resolution by default"
    },
    {
      "commit": "b2cc824abbdce65f2aa1edf94cd22fba3580c610",
      "tree": "c51a8e7ae2562e9ffdd4d726f9098dc7744c9d05",
      "parents": [
        "cf99324bc2af7d91e2a4ffb950b39659297d9d27"
      ],
      "author": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Fri Jul 10 09:09:26 2026 -0400"
      },
      "committer": {
        "name": "Gary Gregory",
        "email": "garydgregory@gmail.com",
        "time": "Fri Jul 10 09:09:26 2026 -0400"
      },
      "message": "Bump github/codeql-action from 4.36.3 to 4.37.0\n"
    },
    {
      "commit": "caa0d3b07e7da4351a97e535b7977a3b6e8b4218",
      "tree": "a3796b0820d95bfcb0aa60d69bdcf2de42f68070",
      "parents": [
        "ad962ce1d418725eb396060c222648bb5390796a",
        "11694688b274c83a60c6c8ae46f197629fa1fb40"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:37:55 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:37:55 2026 +0200"
      },
      "message": "Merge branch \u0027feature/ci-matrix\u0027 into feature/ci-matrix-platforms\n"
    },
    {
      "commit": "11694688b274c83a60c6c8ae46f197629fa1fb40",
      "tree": "2f59ec61fae44bb11c0758810de0de34a16c65ac",
      "parents": [
        "e9f99b9fc4602a90503b94c01cc731c0a76b98d0"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:35:52 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:35:52 2026 +0200"
      },
      "message": "fix: add `|| false` to `continue-on-error`\n"
    },
    {
      "commit": "ad962ce1d418725eb396060c222648bb5390796a",
      "tree": "66fd135bdd55f33c8bb0b79c0e0ae8ae0785b3fe",
      "parents": [
        "fb2bfefa84f81925ae08c07b05816957d1449b74",
        "e9f99b9fc4602a90503b94c01cc731c0a76b98d0"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:31:20 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:31:20 2026 +0200"
      },
      "message": "Merge branch \u0027feature/ci-matrix\u0027 into feature/ci-matrix-platforms\n"
    },
    {
      "commit": "e9f99b9fc4602a90503b94c01cc731c0a76b98d0",
      "tree": "828b5794915924a16e261ac9f16d37afaf18efee",
      "parents": [
        "d2434be81cf013bc9551dae4e4538d460679bd83"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:20:58 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Fri Jul 10 07:21:29 2026 +0200"
      },
      "message": "fix: make GraalVM experimental\n"
    },
    {
      "commit": "fb2bfefa84f81925ae08c07b05816957d1449b74",
      "tree": "3fe91904aeef84962cf3b16a1820f01c1c8e8c7d",
      "parents": [
        "b9964b3428a97bd89ecb2a225bf7d31efe213e80"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 22:54:31 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 22:54:31 2026 +0200"
      },
      "message": "Restructure the build matrix around the axes that matter\n\njava.xml is pure Java, so the OS and JDK axes barely interact. The one\nOS-specific behavior this library touches is file URI / systemId\nnormalization on Windows, which any single Windows job exercises. Crossing\nthree OSes with two JDK endpoints therefore spent jobs on combinations that\ncannot differ, while leaving the axes that do differ underexplored.\n\nRun the JDK majors on Windows, which covers systemId normalization at every\nversion for free, and keep one Linux canary on the current LTS: a\ncase-sensitive filesystem, and what contributors and downstream CI run.\n\nAdd distribution variance, one job each. Semeru 8 and 21 cover OpenJ9, whose\nclass library is the most divergent runtime setup-java offers and the most\nplausible source of surprises in factory lookup and class loading. Zulu is\npinned to an old 8 patch level, verifying the hardening degrades gracefully\non a runtime predating the later jdk.xml.* backports.\n\nDrop macOS: its filesystem is case-insensitive like Windows and POSIX-pathed\nlike Linux, so it is strictly interior to the other two. Vendors that track\nthe OpenJDK Updates projects closely are interchangeable with Temurin here.\n\nNarrow the GraalVM job to the `test` lifecycle; native-image is slow and the\nstatic analysis goals are already covered by the JVM jobs.\n\nTwelve JVM jobs plus the two Android legs, against twenty-one for a full\n3x7 matrix, with strictly better coverage of the axes that produce different\nresults.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "d2434be81cf013bc9551dae4e4538d460679bd83",
      "tree": "e0c61712cb3a3fe07968d0e1abd11f15c4221c90",
      "parents": [
        "b9964b3428a97bd89ecb2a225bf7d31efe213e80"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 22:33:23 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 09 22:33:23 2026 +0200"
      },
      "message": "Fix POM comment\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "b9964b3428a97bd89ecb2a225bf7d31efe213e80",
      "tree": "7c03115ca6516918ecd9f6db64032a6226bce10f",
      "parents": [
        "cf99324bc2af7d91e2a4ffb950b39659297d9d27"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 22:04:32 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 22:04:32 2026 +0200"
      },
      "message": "Run the test suite as a GraalVM native image\n\nAdd a `native-xalan` profile that builds the tests into a native image, and\na GraalVM job to the CI matrix that activates it. This exercises a code path\nthe JVM matrix cannot reach: native-image resolves the JAXP providers at\nbuild time under the closed-world assumption, rather than at run time\nthrough ServiceLoader.\n\nA native binary carries one classpath, so only `test-stockjdk` runs; the\nother JAXP combinations stay on the JVM matrix. Saxon-HE is dropped, since\nits JAXP entry points carry no reachability metadata and every ServiceLoader\nlookup would fail on a missing no-arg constructor. Its `xpath3` group is\nalready excluded from that execution.\n\nApache Xalan supplies TrAX. The stock JDK\u0027s XSLTC compiles each stylesheet\ninto translet bytecode and defines the class at run time, which a\nclosed-world image cannot do: with XSLTC the transform tests fail on `No\nclasses have been predefined during the image build`. Predefining them does\nnot help either, even though JDK-8274535 made the generated bytecode\ndeterministic; the image builder rejects the class with `Cannot define class\ndie.verwandlung.fixture`. Interpretive Xalan, the workaround named on that\nsame issue, needs no bytecode at run time. Xalan and its serializer are\ndeclared as project dependencies rather than through surefire\u0027s\nadditionalClasspathDependencies, which native-image never sees.\n\nReachability metadata comes from the tracing agent rather than a committed\nconfig: Xalan reflects on its template setters and reads serializer defaults\nfrom property files, none of which static analysis sees, and a hand-written\nconfig would rot against every Xalan and JDK update. The attack fixtures are\nembedded explicitly, since the agent records only the resources a given run\nhappened to open.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "55b9b13379b184cc9568a1c70a2bf27f875b734a",
      "tree": "90c48f8f81a323fdc952279fb4baead38084ada5",
      "parents": [
        "72df8f70b2c31d16b3f3fad4d2ad9d8ba30a7b33"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Thu Jul 09 18:20:50 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 09 18:20:50 2026 +0200"
      },
      "message": "Fix `content()` Javadoc\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "72df8f70b2c31d16b3f3fad4d2ad9d8ba30a7b33",
      "tree": "954238ec303e4d4f3dcbc3f3f05abd5d4cbc45bc",
      "parents": [
        "3abfea554c63d0ff170b61acdf42a752b62c3857"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 18:10:24 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 18:10:24 2026 +0200"
      },
      "message": "Split the XSLT payload across two literal result elements\n\nXSLTC compiles each literal text node into a class-file string constant,\nand a CONSTANT_Utf8 entry holds at most 65,535 bytes. A single text node\ncarrying the whole expanded body overflows it: the constant-pool write\nthrows inside the compiler, which swallows the error and hands back a\nTemplates carrying no translet. The permissive control only called\nnewTemplates, so it never saw the failure and passed on a stylesheet that\nhad not compiled.\n\nSpread the same expansions over two literal result elements of 60,000\neach. Every constant stays under the ceiling, while a parser counts\nexpansions across the whole document, so the hardened side still trips\nevery implementation limit, including JDK 17\u0027s 64,000 which neither half\nreaches on its own. The control keeps mirroring its hardened payload.\n\nMake the control instantiate a Transformer instead of stopping at the\ncompile. A failed compile does not necessarily throw: Apache Xalan returns\nnull and XSLTC returns a translet-less Templates, and only building the\ntransformer surfaces either. An oversized text node now fails the control\ninstead of passing it silently.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "3abfea554c63d0ff170b61acdf42a752b62c3857",
      "tree": "a8406aa66cbcbac213969cd70682f4d9d40503cd",
      "parents": [
        "0676eb49dac3e8c872a13f7dd4df46e54de68e1b"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 16:38:16 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 16:38:16 2026 +0200"
      },
      "message": "Fold the Woodstox entity-count lift into liftEntityLimits\n\nThe StAX positive control lifted Woodstox\u0027s own maxEntityCount limit at the\ncall site, next to the JDK properties. Move it into the XMLInputFactory\noverload so every caller lifts the limits of whichever StAX implementation\nis on the classpath, and drop the now redundant Jdk from the method name:\nthe overloads no longer lift only JDK properties.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "0676eb49dac3e8c872a13f7dd4df46e54de68e1b",
      "tree": "3afee644280be7dbcc3d829a96fca4317d10e17d",
      "parents": [
        "67353b1dc2b70376183c6c917b5a17e580db1cd1"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 16:27:12 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 16:27:12 2026 +0200"
      },
      "message": "fix: rename assumeSAXLimitConfigurable\n"
    },
    {
      "commit": "67353b1dc2b70376183c6c917b5a17e580db1cd1",
      "tree": "7d2b0e0faced9a2cc3ac0c3e94965b3c363cc116",
      "parents": [
        "9df3143bd9c0fbf6929346349f1a881a8b64aaa4"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 16:24:54 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 16:24:54 2026 +0200"
      },
      "message": "fix: orphan mention of JDK system properties\n"
    },
    {
      "commit": "9df3143bd9c0fbf6929346349f1a881a8b64aaa4",
      "tree": "3ecbebf190fae342911255dc217242fc68ca1552",
      "parents": [
        "bf4e0847a264504849719744adf1e3f05aeb144a"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 15:44:56 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 15:44:56 2026 +0200"
      },
      "message": "Lift all three JDK entity limits in the positive controls\n\nThe permissive controls lifted only entityExpansionLimit, but a Billion\nLaughs payload also trips totalEntitySizeLimit and entityReplacementLimit,\nboth of which default to 100000 on the JDK. Because the ladder expands to a\nsingle-character body, expanded size equals expansion count, so the 101000\nexpansions chosen to clear the largest expansion limit clear those two as\nwell: the controls failed with JAXP00010004 and JAXP00010007 on every\nexecution backed by the JDK parser (stockjdk, saxon, xalan), while the\nXerces and Woodstox executions passed because their parsers do not enforce\nthe JDK limits.\n\nReplace the single entityExpansionLimit constant with the three-property\nJDK_ENTITY_LIMITS array and lift all of them through liftJdkEntityLimits\noverloads, one per JAXP configuration API. The calls stay best-effort, so\nimplementations that do not recognize the properties keep ignoring them.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "ecda422e59027f8243f7eed4796b63c3c59ba783",
      "tree": "0fbdfa269c4cc3ac4fb3cff3842201024eecd448",
      "parents": [
        "ee98041a9badfcd4b85b6702e81a4d02df669d29"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "piotr@github.copernik.eu",
        "time": "Thu Jul 09 15:33:34 2026 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 09 15:33:34 2026 +0200"
      },
      "message": "Use value for `XmlFactories.harden`\n\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "bf4e0847a264504849719744adf1e3f05aeb144a",
      "tree": "fbd749c81c636403382e7aeb5b68a42c386817f6",
      "parents": [
        "0e2901ab76bce379dff59713ce37ea6430fe3754"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Wed Jul 08 09:23:54 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 13:32:36 2026 +0200"
      },
      "message": "Refactor BillionLaughsTest payloads\n\nBuild every payload from one shared six-level entity ladder and vary\nonly the expanded body: 101000 expansions on the JVM (above every JVM\nparser limit) and 9000000 on Android (above libexpat\u0027s 8 MiB\nbillion-laughs threshold). Positive controls reuse the same payload as\ntheir hardened counterpart, and skip on Android, where the\nentity-expansion limit is not configurable so the payload cannot be\nparsed even without hardening.\n\nLift Woodstox\u0027s own maxEntityCount limit in the StAX positive control,\nwhich ignores the JDK entityExpansionLimit property.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    },
    {
      "commit": "0e2901ab76bce379dff59713ce37ea6430fe3754",
      "tree": "2c6710dc0dc5004b0162b50c2cbf2c08d4e884e7",
      "parents": [
        "cf99324bc2af7d91e2a4ffb950b39659297d9d27"
      ],
      "author": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Sun Jul 05 23:35:27 2026 +0200"
      },
      "committer": {
        "name": "Piotr P. Karwasz",
        "email": "pkarwasz-github@apache.org",
        "time": "Thu Jul 09 13:32:36 2026 +0200"
      },
      "message": "Remove the Limits class\n\nThe Limits class pinned every hardened parser to JDK 25\u0027s secure limit\nvalues. Its real purpose was test determinism, not security: XmlFactories\nonly promises entity expansion \"bounded by the JDK\u0027s default limit\", and\nFEATURE_SECURE_PROCESSING already gives every implementation a limit that\nrejects Billion Laughs (stock JDK 2500/64000, external Xerces and Woodstox\n100000). Limits existed mainly because Xerces and Woodstox ignore the JDK\nsystem properties, so it reflectively installed a Xerces SecurityManager or\nset com.ctc.wstx.* to lower them uniformly to 2500, letting a small test\nfixture trip on every platform.\n\nDrop the class and its call sites in the DOM, SAX, StAX and stock-JDK TrAX\nhardeners; each now leaves the implementation\u0027s own secure-processing limit\nin place. Prune the JaxpSetters overloads left unused.\n\nRework BillionLaughsTest, the only test that depended on the pin: the\nhardened side now uses a 10^6-expansion fixture that exceeds every\nimplementation\u0027s own default (external Xerces\u0027 and Woodstox\u0027s 100000\nincluded), so the parser still aborts, at parse time, on the entity limit.\nThe permissive positive controls keep the small fixture; document on\nunconfiguredTemplatesCompiles why it cannot mirror the hardened payload\n(XSLTC compiles the fully expanded stylesheet and chokes on / overflows its\n65535-byte constant limit, a failure unrelated to hardening).\n\nUpdate threat_model.md: the library no longer reads or pins jdk.xml.*; the\nlimits are each implementation\u0027s secure-processing defaults, tunable via\njdk.xml.* only on the stock JDK.\n\nAssisted-By: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e\n"
    }
  ],
  "next": "ee98041a9badfcd4b85b6702e81a4d02df669d29"
}
