Hi All,

Please review a fix for an issue where a NPE is seen when an attempt is made to print without PrinterResolution attributes in HP Deskjet 1510 printer.

It seems when RasterPrinterJob#setAttributes() is called with no PrinterResolution attribute set, it first checks if PrinterResolution category is supported. If it is supported, then it sees if the supplied resolution value is supported. Now, since no PrinterResolution attribute is set, so isSupportedValue() returns false
[as "printer resolution attribute" object is null]
It then goes to get the default resolution attribute via getDefaultAttributeValue() which calls getDefaultPrinterSettings() and use yRes,Quality from this printer to construct a "PrinterResolution" object.

JDK uses DocumentProperties function[1] to query the printer configuration data in windows and pDevMode->dmFields is initialized to 200bf43
which corresponds to
DM_ORIENTATION | DM_PAPERSIZE | DM_COPIES | DM_DEFAULTSOURCE | DM_PRINTQUALITY | DM_COLOR | DM_DUPLEX  | DM_YRESOLUTION | DM_COLLATE | DM_NUP | DM_MEDIATYPE
so even though DM_YRESOLUTION and DM_PRINTQUALITY indices are set,
it seems for HP Deskjet 1510 printer returns  -3 for both pDevMode->dmYResolution and pDevMode->dmPrintQuality

so then Win32PrintService#getDefaultAttributeValue() checks for yRes,Quality and if they are < 0 then it does not instantiate PrinterResolution class ie printerResAttr object is null

if (res >0) {
 return new PrinterResolution(res, res, PrinterResolution.DPI);
}

causing RasterPrinterJob#setAttributes to cause an NPE when it tries to call printerResAttr.getCrossFeedResolution(ResolutionSyntax.DPI);

We have seen similar issue for Brother HL-2240D series printer, where DM_YRESOLUTION and DM_PRINTQUALITY was not set in dmFields even though  pDevMode->dmYResolution and pDevMode->dmPrintQuality was populated so we check for those values and store that but here the values itself are -ve so it does not get stored and ultimately resulted in returning GETDEFAULT_ERROR(-50)

Proposed fix is to check if printerResAttr is null or not so printerResAttr.getCrossFeedResolution(ResolutionSyntax.DPI); will not be called for bad values.

Bug: https://bugs.openjdk.java.net/browse/JDK-8221411
webrev: http://cr.openjdk.java.net/~psadhukhan/8221411/webrev.0/

Regards
Prasanta
[1] [https://msdn.microsoft.com/en-us/library/windows/desktop/dd183576(v=vs.85).aspx]

Reply via email to