[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-2d-dev
Subject:    Re: [OpenJDK 2D-Dev] [9] RFR JDK-6278300: sun.print.Win32MediaSize deserialization error
From:       Phil Race <philip.race () oracle ! com>
Date:       2016-07-25 20:24:06
Message-ID: 57967566.2060604 () oracle ! com
[Download RAW message or body]

The fix seems wrong to me .. and the problem is not easy.

Windows defines standard paper sizes and we recognise those and will 
always serialise
the "Media" as one of the built-in java pre-defined Media.

But windows printer drivers very  typically define additional 
driver-specific papers,
so at runtime JDK dynamically creates new instances as these are discovered.

They will be instances of Win32MediaSize and their IDs (enum int values) 
will
be entirely dependent on the order they "happened" to be added to the list.

When you serialise this out, all you serialise is
(a) the type (Win32MediaSize) and (b) the int value (see the serialized 
form docs
for EnumSyntax).

When you come to *deserialize* then what happens depends on whether the
code that adds those to the list has been run (or not). If it has, you 
may well
be lucky and get the right intended paper.

If it has not - which is inevitable if you load the preferences in main(..)
before any printing code has run - then the code that initialises the table
has not been run and the int value is meaningless. Pointing it to the ID
in the super-class is wrong. Also you have not run the Win32MediaSize
constructor ! So you will have deserialized a garbage instance .. it
will have an ID that does not correspond to the table, and was meant
to ID some standard paper size. So the fix is probably worse than the bug.

It seems like there should be a readResolve() for Win32MediaSize that
first initialises the table.

And it is only *this simple* (yes, I mean that) because you only have one
printer involved. Get 4 printers with custom IDs and you don't even know
in which order these printers had their IDs initialised.

The  documented serialised form leaves you with essentially insufficient 
information.
It seems like Win32MediaSize needs a serialised form that includes the 
extra info.
But if you "delete" the printer and run the app you now have useless 
serialised data
and need to esstablish a policy around that.

Also it seems likely we have the same issue in the CUPS code ..

This is a non-trivial bug and will likely take a lot of careful work to
figure out all the spec/compat/behavioural issues.


-phil.





On 07/15/2016 02:36 AM, Prasanta Sadhukhan wrote:
> Hi All,
> 
> Bug: https://bugs.openjdk.java.net/browse/JDK-6278300
> 
> Please review a fix for an issue where it is seen that
> Deserialization of a javax.print.attribute.standard.MediaPrintableArea 
> printer attribute fails when the serialization happened in a prior 
> invocation of the program
> only for a *non-standard* page size say 4"x6"
> 
> It is because EnumSyntax.readResolve() tries to get the EnumSyntax[] 
> table from Win32MediaSize when the objects are read
> and if the EnumSyntax table is not initialized or 0 in length, then 
> readResolve() will find the object value being read is not in the 
> EnumSyntax table and will throw this InvalidObjectException
> 
> java.io.InvalidObjectException: Integer value = 9 not in valid range 
> 0..-1for class class sun.print.Win32MediaSize
> at 
> javax.print.attribute.EnumSyntax.readResolve(java.desktop@9-internal/EnumSyntax.java:204)
>  at 
> jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-internal/Native 
> Method)
> at 
> jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@9-internal/NativeMethodAccessorImpl.java:62)
>  at 
> jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@9-internal/DelegatingMethodAccessorImpl.java:43)
>  at 
> java.lang.reflect.Method.invoke(java.base@9-internal/Method.java:533)
> at 
> java.io.ObjectStreamClass.invokeReadResolve(java.base@9-internal/ObjectStreamClass.java:1150)
>  at 
> java.io.ObjectInputStream.readOrdinaryObject(java.base@9-internal/ObjectInputStream.java:1835)
>  at 
> java.io.ObjectInputStream.readObject0(java.base@9-internal/ObjectInputStream.java:1371)
>  at 
> java.io.ObjectInputStream.readObject(java.base@9-internal/ObjectInputStream.java:371)
>  
> When the printDialog() is invoked, then EnumSyntax table will be 
> initialised to the current paper ids. But, if printDIalog() is invoked 
> AFTER objects are deserialised, we run into this problem of enumTable 
> being 0 in length.
> 
> Proposed fix is, to check if the enumtable is not initialised, then 
> fallback to the supported media size enum table.
> 
> webrev: http://cr.openjdk.java.net/~psadhukhan/6278300/webrev.00/
> 
> I made it noreg-hard as it needs a custom paper size to be added to 
> printer media list before invoking the serialization testcase present 
> in JBS bug entry.
> 
> Regards
> Prasanta


[Attachment #3 (text/html)]

<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">The fix seems wrong to me .. and the
      problem is not easy.<br>
      <br>
      Windows defines standard paper sizes and we recognise those and
      will always serialise<br>
      the "Media" as one of the built-in java pre-defined Media.<br>
      <br>
      But windows printer drivers very   typically define additional
      driver-specific papers,<br>
      so at runtime JDK dynamically creates new instances as these are
      discovered.<br>
      <br>
      They will be instances of Win32MediaSize and their IDs (enum int
      values) will<br>
      be entirely dependent on the order they "happened" to be added to
      the list.<br>
      <br>
      When you serialise this out, all you serialise is<br>
      (a) the type (Win32MediaSize) and (b) the int value (see the
      serialized form docs<br>
      for EnumSyntax).<br>
      <br>
      When you come to *deserialize* then what happens depends on
      whether the<br>
      code that adds those to the list has been run (or not). If it has,
      you may well<br>
      be lucky and get the right intended paper.<br>
      <br>
      If it has not - which is inevitable if you load the preferences in
      main(..)<br>
      before any printing code has run - then the code that initialises
      the table<br>
      has not been run and the int value is meaningless. Pointing it to
      the ID<br>
      in the super-class is wrong. Also you have not run the
      Win32MediaSize<br>
      constructor ! So you will have deserialized a garbage instance ..
      it<br>
      will have an ID that does not correspond to the table, and was
      meant<br>
      to ID some standard paper size. So the fix is probably worse than
      the bug.<br>
      <br>
      It seems like there should be a readResolve() for Win32MediaSize
      that<br>
      first initialises the table.<br>
      <br>
      And it is only *this simple* (yes, I mean that) because you only
      have one<br>
      printer involved. Get 4 printers with custom IDs and you don't
      even know<br>
      in which order these printers had their IDs initialised.<br>
      <br>
      The   documented serialised form leaves you with essentially
      insufficient information.<br>
      It seems like Win32MediaSize needs a serialised form that includes
      the extra info.<br>
      But if you "delete" the printer and run the app you now have
      useless serialised data<br>
      and need to esstablish a policy around that.<br>
      <br>
      Also it seems likely we have the same issue in the CUPS code ..<br>
      <br>
      This is a non-trivial bug and will likely take a lot of careful
      work to<br>
      figure out all the spec/compat/behavioural issues.<br>
      <br>
      <br>
      -phil.<br>
      <br>
      <br>
      <br>
      <br>
      <br>
      On 07/15/2016 02:36 AM, Prasanta Sadhukhan wrote:<br>
    </div>
    <blockquote cite="mid:5788AEB1.9010709@oracle.com" type="cite">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      Hi All,<br>
      <br>
      Bug: <a moz-do-not-send="true" class="moz-txt-link-freetext"
        href="https://bugs.openjdk.java.net/browse/JDK-6278300">https://bugs.openjdk.java.net/browse/JDK-6278300</a><br>
  <br>
      Please review a fix for an issue where it is seen that<br>
      Deserialization of a
      javax.print.attribute.standard.MediaPrintableArea printer
      attribute fails when the serialization happened in a prior
      invocation of the program<br>
      only for a <b>non-standard</b> page size say 4"x6"<br>
      <br>
      It is because EnumSyntax.readResolve() tries to get the
      EnumSyntax[] table from Win32MediaSize when the objects are read <br>
      and if the EnumSyntax table is not initialized or 0 in length,
      then readResolve() will find the object value being read is not in
      the EnumSyntax table and will throw this InvalidObjectException<br>
      <br>
      java.io.InvalidObjectException: Integer value = 9 not in valid
      range 0..-1for class class sun.print.Win32MediaSize<br>
             at
      javax.print.attribute.EnumSyntax.readResolve(<a
        moz-do-not-send="true" class="moz-txt-link-abbreviated"
        href="mailto:java.desktop@9-internal/EnumSyntax.java:204">java.desktop@9-internal/EnumSyntax.java:204</a>)<br>
  at
      jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@9-internal/Native


      Method)<br>
             at
      jdk.internal.reflect.NativeMethodAccessorImpl.invoke(<a
        moz-do-not-send="true" class="moz-txt-link-abbreviated"
        href="mailto:java.base@9-internal/NativeMethodAccessorImpl.java:62">java.base@9-internal/NativeMethodAccessorImpl.java:62</a>)<br>
  at
      jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(<a
        moz-do-not-send="true" class="moz-txt-link-abbreviated"
        href="mailto:java.base@9-internal/DelegatingMethodAccessorImpl.java:43">java.base@9-internal/DelegatingMethodAccessorImpl.java:43</a>)<br>
  at java.lang.reflect.Method.invoke(<a moz-do-not-send="true"
        class="moz-txt-link-abbreviated"
        href="mailto:java.base@9-internal/Method.java:533">java.base@9-internal/Method.java:533</a>)<br>
  at
      java.io.ObjectStreamClass.invokeReadResolve(<a
        moz-do-not-send="true" class="moz-txt-link-abbreviated"
        href="mailto:java.base@9-internal/ObjectStreamClass.java:1150">java.base@9-internal/ObjectStreamClass.java:1150</a>)<br>
  at
      java.io.ObjectInputStream.readOrdinaryObject(<a
        moz-do-not-send="true" class="moz-txt-link-abbreviated"
        href="mailto:java.base@9-internal/ObjectInputStream.java:1835">java.base@9-internal/ObjectInputStream.java:1835</a>)<br>
  at
      java.io.ObjectInputStream.readObject0(<a moz-do-not-send="true"
        class="moz-txt-link-abbreviated"
        href="mailto:java.base@9-internal/ObjectInputStream.java:1371">java.base@9-internal/ObjectInputStream.java:1371</a>)<br>
  at
      java.io.ObjectInputStream.readObject(<a moz-do-not-send="true"
        class="moz-txt-link-abbreviated"
        href="mailto:java.base@9-internal/ObjectInputStream.java:371">java.base@9-internal/ObjectInputStream.java:371</a>)<br>
  <br>
      When the printDialog() is invoked, then EnumSyntax table will be
      initialised to the current paper ids. But, if printDIalog() is
      invoked AFTER objects are deserialised, we run into this problem
      of enumTable being 0 in length.<br>
      <br>
      Proposed fix is, to check if the enumtable is not initialised,
      then fallback to the supported media size enum table.<br>
      <br>
      webrev: <a moz-do-not-send="true" class="moz-txt-link-freetext"
        href="http://cr.openjdk.java.net/%7Epsadhukhan/6278300/webrev.00/">http://cr.openjdk.java.net/~psadhukhan/6278300/webrev.00/</a><br>
  <br>
      I made it noreg-hard as it needs a custom paper size to be added
      to printer media list before invoking the serialization testcase
      present in JBS bug entry.<br>
      <br>
      Regards<br>
      Prasanta<br>
    </blockquote>
    <br>
  </body>
</html>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic