empira / PDFsharp

PDFsharp and MigraDoc Foundation for .NET 6 and .NET Framework
https://docs.pdfsharp.net/
Other
492 stars 114 forks source link

Exception: WidthCannotBeNegative #173

Open mnadeem-mercedes-hpp opened 1 week ago

mnadeem-mercedes-hpp commented 1 week ago

https://github.com/empira/PDFsharp/blob/5fbf6ed14740bc4e16786816882d32e43af3ff5d/src/foundation/src/PDFsharp/src/PdfSharp/Fonts.Internal/FontHelper.cs#L169

The integer width gets negative once the value of width tries to go above 2147483647 (i.e. maximum integer value).

I have a string with a length of a little over 9.8 million characters and when I try to measure width for that string it throws following exception

Exception Message: WidthCannotBeNegative

Stack: at PdfSharp.Fonts.Internal.FontHelper.MeasureString(CodePointGlyphIndexPair[] codeRun, XFont font) at PdfSharp.Drawing.XGraphics.MeasureString(String text, XFont font, XStringFormat stringFormat) at PdfSharp.Drawing.XGraphics.MeasureString(String text, XFont font)

ThomasHoevel commented 1 week ago

What's the point of measuring 9.8 million characters? Do you want to write them all in a single line? That amount of text fills about 30,000 regular pages and is not normally rendered in a single line.

mnadeem-mercedes-hpp commented 1 week ago

In our implementation, the width from MeasureString method only matters as long as it is less than PageSize.Width otherwise the string is broken into multiple lines that can fit into the PageSize.Width.

ThomasHoevel commented 1 week ago

If the text length is more than e.g. 1000 characters, your code could (and IMHO should) start line-breaking without calling MeasureString. Should increase the performance of the code, too.

I don't think we should change MeasureString from "int" to "longint", as this would make the code slower.

mnadeem-mercedes-hpp commented 1 week ago

I agree - there's no point in changing MeasureString to longint, however uint or ushort can be considered, just to avoid going negative?

ThomasHoevel commented 1 week ago

With uint we risk having an undetected overflow at around 19 million characters. We'll think about it.