Skip to content

fix(pptx): reject adjust handles undeclared by the preset geometry (#235) - #238

Open
jasonwei1002 wants to merge 1 commit into
iOfficeAI:mainfrom
jasonwei1002:fix/reject-undeclared-adjust-handles
Open

fix(pptx): reject adjust handles undeclared by the preset geometry (#235)#238
jasonwei1002 wants to merge 1 commit into
iOfficeAI:mainfrom
jasonwei1002:fix/reject-undeclared-adjust-handles

Conversation

@jasonwei1002

@jasonwei1002 jasonwei1002 commented Jul 17, 2026

Copy link
Copy Markdown

Fixes #235.

Root cause

Real PowerPoint validates every <a:gd name="…"> in a shape's avLst against the guide names the preset's ECMA-376 definition declares, and refuses the file (0x80070570, "repair/corrupt" dialog) on any mismatch. ApplyAdjustHandles already guarded two slices of this (the R18 donut/noSmoking remap and the R19b multi-guide subset fix for 5 star/hexagon presets), but presets outside those hand tables fell through to verbatim pass-through — most damagingly presets that declare no adjust guides at all (rect, ellipse, line, … 64 of the 187 presets), where any authored adj= silently produces an unopenable file while validate stays green.

Change

One mechanism replaces the two hand-maintained tables: PresetAdjustGuides, a complete map of all 187 preset geometries → declared guide names + spec-default formulas, generated from the ECMA-376 presetShapeDefinitions.xml. ApplyAdjustHandles now authors the avLst strictly per the preset's declaration:

  • Zero-guide presets: adj= is rejected with an actionable error instead of writing a corrupt file.
  • Single-guide presets: the position-0 name is remapped to the declared name — generalizing the existing donut/noSmoking special case to all of them (e.g. adj1 on roundRect now yields adj instead of a corrupt file); extra handles are rejected.
  • Multi-guide presets: undeclared names are rejected listing the valid ones, and the complete guide set is always emitted with spec defaults filling unsupplied guides — extending the existing hexagon/star5/6/7/10 behavior to every multi-guide preset, which fixes the same subset corruption for e.g. round2SameRect authored with only adj1.

The generated defaults for the 5 previously hand-listed presets are byte-identical to the old MultiGuidePresetDefaults entries. Unknown/custom presets keep today's pass-through behavior.

Verification (macOS, net10.0 build of this branch)

$ officecli add t.pptx '/slide[1]' --type shape --prop geometry=rect ... --prop adj="adj:val 14000"
Error: Preset geometry 'rect' has no adjust handles; remove the adj= property. ...

$ ... --prop geometry=roundRect --prop adj="adj1:val 20000"     # remapped
<a:prstGeom prst="roundRect"><a:avLst><a:gd name="adj" fmla="val 20000"/></a:avLst>

$ ... --prop geometry=round2SameRect --prop adj="adj1:val 20000" # completed
<a:gd name="adj1" fmla="val 20000"/><a:gd name="adj2" fmla="val 0"/>

$ ... --prop geometry=downArrow --prop adj="adj3:val 1"
Error: Adjust handle 'adj3' is not declared by preset geometry 'downArrow'. Valid handles: adj1, adj2.

Output files re-verified with an independent reader (python-pptx). dotnet build clean (the single CS8602 warning is pre-existing in ExcelHandler.SheetShift.cs).

Per CONTRIBUTING Rule 1 this PR is one atomic change: "author avLst strictly per the preset's ECMA-376 declaration". A follow-up candidate (not included): make validate flag pre-existing illegal <a:gd> entries in already-authored files using the same table.

…OfficeAI#235)

PowerPoint reports a file as corrupt (0x80070570) when a shape's avLst
contains a <a:gd> whose name is not declared by the preset's ECMA-376
definition — most commonly an adj value on a preset with no adjust
handles at all (rect, ellipse, line, ...). officecli previously wrote
such files without complaint and validate stayed green.

Replace the two hand-maintained partial tables (MultiGuidePresetDefaults,
CanonicalAdjName) with PresetAdjustGuides, a complete table of all 187
preset geometries' declared guide names and spec-default formulas,
generated from ECMA-376 presetShapeDefinitions.xml. ApplyAdjustHandles
now:

- rejects any adj= spec on a preset that declares no adjust handles,
  with an actionable error instead of an unopenable file;
- rejects guide names not declared by multi-guide presets, listing the
  valid names;
- generalizes the single-guide remap (donut/noSmoking special case) to
  every single-guide preset;
- emits the complete guide set for every multi-guide preset (previously
  only hexagon/star5/star6/star7/star10), fixing the same 0x80070570
  subset corruption for e.g. round2SameRect authored with only adj1.

Fixes iOfficeAI#235
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] pptx: add/validate accept adjust-value <a:gd> on presets without adjust handles (rect/ellipse) — PowerPoint reports file as corrupt

1 participant