Fix invoice-image code-review findings: aspect ratio, whitelist config, stale refs
- MigraDocExtensions: fix a bug where capping an oversized explicit width+height image re-derived the other dimension from the image's native pixel ratio instead of scaling both sides uniformly, silently distorting a deliberately non-native-ratio (e.g. stretched) image. - InvoiceService: derive the mfr-portal image whitelist prefix from the existing Fds:MFR_host config setting (via MFRClientConfig.RestRoot) instead of a second hardcoded literal, so it can't drift from the actual configured host; parse <img> sources with HtmlAgilityPack (already used by the PDF's own HTML converter) instead of a regex, so a decoy attribute like data-src can't be picked up in place of the real src; dedup fetch URLs with a HashSet instead of O(n^2) List scanning; reuse FuchsPdf.MigraDocFilenameFromByteArray instead of re-spelling the "base64:" prefix. - Fix a stale log message and comment left over from the GenerateInvoicePdf -> GenerateInvoicePdfAsync rename, and update INVOICE_LIFECYCLE.md's references to the old sync method name. - Add tests for the config-derived whitelist, a decoy-attribute src, and the 20-image-per-invoice fetch cap boundary. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1166,7 +1166,8 @@ public static class FuchsPdf
|
||||
img.Top = ShapePosition.Top;
|
||||
}
|
||||
|
||||
private static string MigraDocFilenameFromByteArray(byte[] image) =>
|
||||
/// <summary>Formats bytes as a MigraDoc-recognized inline image source ("base64:...").</summary>
|
||||
internal static string MigraDocFilenameFromByteArray(byte[] image) =>
|
||||
"base64:" + Convert.ToBase64String(image);
|
||||
|
||||
private static byte[] ImageToByteArray(System.Drawing.Image img)
|
||||
|
||||
@@ -129,8 +129,26 @@ namespace MigraDoc.Extensions.Html
|
||||
|
||||
double? wPx = ReadPxDimension(n, "width");
|
||||
double? hPx = ReadPxDimension(n, "height");
|
||||
if (wPx is > 0 && hPx is > 0) { img.LockAspectRatio = false; img.Width = PxToUnit(wPx.Value); img.Height = PxToUnit(hPx.Value); }
|
||||
else if (wPx is > 0) img.Width = PxToUnit(wPx.Value);
|
||||
if (wPx is > 0 && hPx is > 0)
|
||||
{
|
||||
// Both explicit: honour the HTML's (possibly non-native, e.g. a stretched banner)
|
||||
// aspect ratio. Enforcing the cap must scale both dimensions by the same factor —
|
||||
// re-enabling LockAspectRatio here would make MigraDoc recompute the other side from
|
||||
// the image's *native* pixel ratio instead, silently discarding the explicit value.
|
||||
img.LockAspectRatio = false;
|
||||
img.Width = PxToUnit(wPx.Value);
|
||||
img.Height = PxToUnit(hPx.Value);
|
||||
double scale = Math.Min(1.0, Math.Min(
|
||||
MaxInlineImageWidth.Centimeter / img.Width.Centimeter,
|
||||
MaxInlineImageHeight.Centimeter / img.Height.Centimeter));
|
||||
if (scale < 1.0)
|
||||
{
|
||||
img.Width = Unit.FromCentimeter(img.Width.Centimeter * scale);
|
||||
img.Height = Unit.FromCentimeter(img.Height.Centimeter * scale);
|
||||
}
|
||||
return para;
|
||||
}
|
||||
if (wPx is > 0) img.Width = PxToUnit(wPx.Value);
|
||||
else if (hPx is > 0) img.Height = PxToUnit(hPx.Value);
|
||||
|
||||
if (img.Width > MaxInlineImageWidth) { img.LockAspectRatio = true; img.Width = MaxInlineImageWidth; }
|
||||
|
||||
Reference in New Issue
Block a user