Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-53290

QWindowsPrintDevice::defaultPrintDeviceId() may crash, when no printers are installed

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • 5.9.2
    • 5.5.1, 5.6.0, 5.15.8
    • GUI: Printing
    • None
    • Windows 2012 R2, Qt5.5.1, MSVC2013, 64-Bit
    • e7471da4d6e025efc6fe2a8e9c1890e593b2d6b2

    Description

      Analyzing a crash from a customer, we discoverd this function as the source for it:

      QString QWindowsPrintDevice::defaultPrintDeviceId()
      {
          DWORD size = 0;
          GetDefaultPrinter(NULL, &size);
          QScopedArrayPointer<wchar_t> name(new wchar_t[size]);
          GetDefaultPrinter(name.data(), &size);
          return QString::fromWCharArray(name.data());
      }
      

      Main requirement: No printers are installed on the windows system!

      The first call of GetDefaultPrinter() will return ERROR_FILE_NOT_FOUND when no printers are installed.
      size will be still zero, so the wchar_t-array allocate nothing, that means the memory name is pointing to is undefined.
      The second call of GetDefaultPrinter() doesn't change anything!

      The crash occures in QString::fromWCharArray(name.data());, because no buffer-size information is passed, so finally QString::fromUtf16() tries to determine the size of the buffer by finding a null-termination until size overflows after reaching MAX_INT.
      Even when there is no overflow or crash, it leads to an undefined content of the QString.

      The overflow depends on the state of the memory, so it is not easy to reproduce it!

      Fix would be either to leave the function with a null-QString after GetDefaultPrinter() returned ERROR_FILE_NOT_FOUND or to pass the value of the DWORD size as an int to QString::fromWCharArray() to skip the length detection.

      Prefered fix:

      QString QWindowsPrintDevice::defaultPrintDeviceId()
      {
         DWORD size = 0;
         if (!GetDefaultPrinter(NULL, &size) && size > 0)
         {
            QScopedArrayPointer<wchar_t> name(new wchar_t[size]);
            if (GetDefaultPrinter(name.data(), &size))
               return QString::fromWCharArray(name.data());
         }
         return QString();
      }
      

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            dt Daniel Teske
            Alex_S Alexander Shaya
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews