JackTrapper / DelphiBugs

Bug tracker for Delphi
7 stars 2 forks source link

TPrinter.SetPrinter fails to check return value of DocumentProperties #7

Open JackTrapper opened 5 years ago

JackTrapper commented 5 years ago

Tested

Background

In order to figure out the size of memory that needs to be allocated for a subsequent call to DocumentProperties, the SetPrinter method calls:

Vcl.Printers.pas:

DocumentProperties(0, FPrinterHandle, ADevice, nil, nil, 0);

MSDN documents that DocumentProperties will return the number of bytes required when you pass fMode as 0:

If the fMode parameter is zero, the return value is the size of the buffer required to contain the printer driver initialization data.

If the function fails, the return value is less than zero.

But rather than checking if the function failed, it immediately tries to allocate a negative amount of bytes:

DeviceMode := Marshal.AllocHGlobal(DocumentProperties(0, FPrinterHandle, ADevice, DeviceMode, DeviceMode, 0));

This is then also invalid, and is a chain of uncaught failures.

Write correct code

Check the function return value:

Vcl.Printers.Pas:

    procedure TPrinter.SetPrinter(ADevice, ADriver, APort: PChar; ADeviceMode: THandle);
    var
      nBytesRequired: Longint;

      nBytesRequired := DocumentProperties(0, FPrinterHandle, ADevice, nil, nil, 0);
      if (nBytesRequired >= 0) then
        DeviceMode := GlobalAlloc(GHND, nBytesRequired)
      else
        DeviceMode := 0;