Hi Sergey,

It will be pushed after removing the redundant code.
Please find the webrev:
http://cr.openjdk.java.net/~jdv/8044289/webrev.07/ 

Thanks,
Jay

-----Original Message-----
From: Sergey Bylokhov 
Sent: Tuesday, April 05, 2016 8:05 PM
To: Jayathirth D V
Cc: 2d-dev@openjdk.java.net
Subject: Re: [OpenJDK 2D-Dev] Review Request for JDK-8044289 : In 
ImageIO.read() and write() NPE is not handled properly for stream

On 30.03.16 9:48, Jayathirth D V wrote:
> Thanks for pointing it out. It looks like redundant try-catch block.

There is small code clean up is possible after your latest change:
1587 ImageOutputStream stream = null;
1588 stream = createImageOutputStream(output);

I guess such code is redundant too.

> I have removed these blocks in write() methods so that we are handling "cant 
> create cache file" exception in common way in all read() and write() methods.
> Also I have updated test case description to hold true for only those read() 
> and write() methods where we are using createImageXXXStream() for readability.
>
> Please find updated webrev for review:
> http://cr.openjdk.java.net/~jdv/8044289/webrev.06/
>
> After CCC is done we will push above change to repo.
>
> Thanks,
> Jay
>
> -----Original Message-----
> From: Sergey Bylokhov
> Sent: Tuesday, March 29, 2016 6:11 PM
> To: Philip Race; Jayathirth D V
> Cc: 2d-dev@openjdk.java.net
> Subject: Re: [OpenJDK 2D-Dev] Review Request for JDK-8044289 : In 
> ImageIO.read() and write() NPE is not handled properly for stream
>
> I am not sure what is the reason of this code?
> 1546         try {
> 1547             output.delete();
> 1548             stream = createImageOutputStream(output);
> 1549         } catch (IOException e) {
> 1550             throw e;
> 1551         }
>
> On 29.03.16 1:12, Philip Race wrote:
>> This all looks fine to me. Although no new Exception types are thrown 
>> I think we need a CCC anyway, so please prepare and get that approved 
>> before pushing.
>>
>> -phil.
>>
>> On 3/28/16, 3:30 AM, Jayathirth D V wrote:
>>>
>>> Hi Phil,
>>>
>>> After discussion with Sergey we have come to conclusion that Sergey 
>>> is okay with throwing exception or returning null/false.
>>>
>>> So I have modified the webrev to throw exception.
>>>
>>> Also in write() I have modified the catch block to just throw the 
>>> caught exception without adding message since it will create 
>>> confusion between the case where we are not able to create cache and 
>>> when
>>> createImageOutputStream() returns null.
>>>
>>> Regarding catch block of createImageOutputStream() only when we 
>>> usecache is true we use FileCacheImageOutputStream() and it throws 
>>> IOException so I think there is no need to add extra check before 
>>> throwing IOException.
>>>
>>> Please find updated webrev for review :
>>>
>>> http://cr.openjdk.java.net/~jdv/8044289/webrev.04/
>>> <http://cr.openjdk.java.net/%7Ejdv/8044289/webrev.04/>
>>>
>>> Thanks,
>>>
>>> Jay
>>>
>>> *From:*Jayathirth D V
>>> *Sent:* Thursday, March 24, 2016 3:52 PM
>>> *To:* Philip Race
>>> *Cc:* Sergey Bylokhov; 2d-dev@openjdk.java.net
>>> *Subject:* RE: [OpenJDK 2D-Dev] Review Request for JDK-8044289 : In
>>> ImageIO.read() and write() NPE is not handled properly for stream
>>>
>>> Hi Phil,
>>>
>>> We can change the code to something like :
>>>
>>> 1522      * @return <code>false</code> if no appropriate writer is
>>> found or
>>> 1523      * when needed stream is null.
>>>
>>> 1545         try {
>>> 1546             output.delete();
>>> 1547             stream = createImageOutputStream(output);
>>> 1548         } catch (IOException e) {
>>> 1549 *throw e;*
>>> 1550         }
>>>
>>> In this case we will be throwing IOException when we are not able to 
>>> create cache file and stream is null.
>>>
>>> And return null/false when createImageXXXStream returns null. Also 
>>> we can add check before throwing IIOException from 
>>> createImageXXXStream for usecache.
>>>
>>> 350
>>>   351         boolean usecache = getUseCache() && hasCachePermission();
>>> 352
>>>   353         while (iter.hasNext()) {
>>> 354             ImageInputStreamSpi spi = iter.next();
>>> 355             if (spi.getInputClass().isInstance(input)) {
>>> 356                 try {
>>> 357                     return spi.createInputStreamInstance(input,
>>> 358                                                          usecache,
>>> 359
>>> getCacheDirectory());
>>> 360                 } catch (IOException e) {
>>> 361 *if (usecache)*
>>> 362                         throw new IIOException("Can't create cache
>>> file!", e);
>>> 363                 }
>>> 364             }
>>> 365         }
>>>
>>> This will be one of the approach.
>>>
>>> Or we can throw IOException in all the cases with additional check 
>>> in createImageXXXStream for usecache. This will be like throwing 
>>> IOException when createImageXXXStream returns null/false or it 
>>> throws IIOException when it cant create cache file. This will be 
>>> another approach. Please let us know your inputs.
>>>
>>> Thanks,
>>>
>>> Jay
>>>
>>> *From:*Philip Race
>>> *Sent:* Thursday, March 24, 2016 5:10 AM
>>> *To:* Jayathirth D V
>>> *Cc:* Sergey Bylokhov; 2d-dev@openjdk.java.net 
>>> <mailto:2d-dev@openjdk.java.net>
>>> *Subject:* Re: [OpenJDK 2D-Dev] Review Request for JDK-8044289 : In
>>> ImageIO.read() and write() NPE is not handled properly for stream
>>>
>>> I don't think this is ready and we need to discuss whether to rework it.
>>>
>>> In general I think I prefer IIO rather than null when we have a stream 
>>> problem.
>>>
>>>
>>> For one thing you have this change :-
>>>
>>> 1522      * @return <code>false</code> if no appropriate writer is
>>> found or
>>> 1523      * not able to create required ImageOutputStream.
>>> yet the implementation says :-
>>> 1545         try {
>>> 1546             output.delete();
>>> 1547             stream = createImageOutputStream(output);
>>> 1548         } catch (IOException e) {
>>> 1549             throw new IIOException("Can't create output stream!", e);
>>> 1550         }
>>> So whilst "null" would mean we cannot find an IOS SPI it isn't the 
>>> only reason we fail to create the IOS A null return seems to get 
>>> passed through to doWrite()  which probably throws IIOE And I think 
>>> that the implementation is actually right here where it throws an 
>>> exception.
>>> The ability to create an image input or output stream could be 
>>> because of some kind of problem opening the file, or with the IIS or 
>>> IOS implementations - like they were de-registered. I think in many 
>>> if not all of these cases IOE - or IIOE is what we want.
>>> Also since we call createImageInputStream() - which is public - we 
>>> need to look at that, and what it does, which is also something to consider.
>>> If it returns null, that seems to mean that no suitable SPI is 
>>> registered which can only happen if they are de-registered. For the 
>>> methods where we use  createImageInputStream() I think it is fair to 
>>> turn that into IIOE BTW I note that the code there says :-
>>>    350
>>>    351         boolean usecache = getUseCache() && hasCachePermission();
>>>    352
>>>    353         while (iter.hasNext()) {
>>>    354             ImageInputStreamSpi spi = iter.next();
>>>    355             if (spi.getInputClass().isInstance(input)) {
>>>    356                 try {
>>>    357                     return spi.createInputStreamInstance(input,
>>>    358                                                          usecache,
>>>    359                                                          
>>> getCacheDirectory());
>>>    360                 } catch (IOException e) {
>>>    361                     throw new IIOException("Can't create cache 
>>> file!", e);
>>>    362                 }
>>>    363             }
>>>    364         }
>>> So far I can see that means it will claim any Exception that is 
>>> generated is because it could not create the cache file without any proof 
>>> of that and even if "useCache" is false.
>>> It seems to imply to me that the author was not considering things 
>>> like someone passing a closed InputStream .. probably we ought to be 
>>> more vague in this case or look more deeply at what we can tell from 
>>> whether it is IIOE or IOE.
>>> -phil.
>>>
>>> On 3/22/16, 10:49 AM, Jayathirth D V wrote:
>>>
>>>      Thanks for the review Sergey.
>>>
>>>      Can I get +1 for this please?
>>>
>>>      -Jay
>>>
>>>      -----Original Message-----
>>>
>>>      From: Sergey Bylokhov
>>>
>>>      Sent: Tuesday, March 22, 2016 9:52 PM
>>>
>>>      To: Jayathirth D V; Philip Race
>>>
>>>      Cc:2d-dev@openjdk.java.net <mailto:2d-dev@openjdk.java.net>
>>>
>>>      Subject: Re: [OpenJDK 2D-Dev] Review Request for JDK-8044289 : 
>>> In
>>> ImageIO.read() and write() NPE is not handled properly for stream
>>>
>>>      This fix looks fine to me.
>>>
>>>      At least it made all code work in a similar way. But probably someone 
>>> will have other opinion?
>>>
>>>      On 22.03.16 12:34, Jayathirth D V wrote:
>>>
>>>          Hi Sergey,
>>>
>>>          I have unified changes related to ImageIO.read() and 
>>> ImageIO.write().
>>>
>>>          In case of  read() we will be returning null when 
>>> createImageInputStream() returns null.
>>>
>>>          In case of write() we will be returning false when 
>>> createImageOutputStream() returns null.
>>>
>>>          Please find updated webrev for review:
>>>
>>>          http://cr.openjdk.java.net/~jdv/8044289/webrev.03/
>>>          <http://cr.openjdk.java.net/%7Ejdv/8044289/webrev.03/>
>>>
>>>          Thanks,
>>>
>>>          Jay
>>>
>>>          -----Original Message-----
>>>
>>>          From: Sergey Bylokhov
>>>
>>>          Sent: Tuesday, March 22, 2016 7:39 AM
>>>
>>>          To: Jayathirth D V; Philip Race
>>>
>>>          Cc:2d-dev@openjdk.java.net <mailto:2d-dev@openjdk.java.net>
>>>
>>>          Subject: Re: [OpenJDK 2D-Dev] Review Request for 
>>> JDK-8044289
>>> : In
>>>
>>>          ImageIO.read() and write() NPE is not handled properly for 
>>> stream
>>>
>>>          Hi, Jay.
>>>
>>>          Since we decided to update the specification we get an additional 
>>> flexibility in the fix, because we can update the "@exception IOException" 
>>> part of javadoc and describe that it can be thrown if ImageXXXStream cannot 
>>> be created.
>>>
>>>          I don't see a big differences of both approaches in case of 
>>> write() methods, but in case of read(which has the similar issue but was 
>>> skipped in the fix) there is a difference.
>>>
>>>          Note that the read(File) unlike other methods throws the 
>>> unspecified
>>>
>>>          IIOException exception if ImageXXXStream cannot be created.
>>> We can
>>>
>>>          think about unification of read/write methods in ImageIO. 
>>> Hmm but even
>>>
>>>          then
>>>
>>>          read() in some cases will return null and in some cases throw an 
>>> exception....
>>>
>>>          and createImageInputStream/createImageOutputStream() will look 
>>> alien as they always return null not an exception.
>>>
>>>          Another possible unification is to update javadoc for all 
>>> methods,
>>>
>>>          that they will return null if related providers are not 
>>> found(in this
>>>
>>>          case "throw new IIOException("Can't create an ImageInputStream!"))"
>>>
>>>          should be removed from read(File);
>>>
>>>          On 21.03.16 10:26, Jayathirth D V wrote:
>>>
>>>              Hi Sergey,
>>>
>>>              For the second approach I have created webrev for review.
>>>
>>>              Please review updated webrev :
>>>
>>>              http://cr.openjdk.java.net/~jdv/8044289/webrev.02/
>>>              <http://cr.openjdk.java.net/%7Ejdv/8044289/webrev.02/>
>>>
>>>              Thanks,
>>>
>>>              Jay
>>>
>>>              -----Original Message-----
>>>
>>>              From: Jayathirth D V
>>>
>>>              Sent: Friday, March 18, 2016 2:23 PM
>>>
>>>              To: Sergey Bylokhov
>>>
>>>              Cc:2d-dev@openjdk.java.net 
>>> <mailto:2d-dev@openjdk.java.net>; Philip Race
>>>
>>>              Subject: RE: [OpenJDK 2D-Dev] Review Request for
>>> JDK-8044289 : In
>>>
>>>              ImageIO.read() and write() NPE is not handled properly 
>>> for stream
>>>
>>>              Hi Sergey,
>>>
>>>              Thanks for your inputs.
>>>
>>>              Indeed all the null values returned by 
>>> createImageInputStream() and createImageInputStream() are valid only.
>>>
>>>              I went through the code more and found that there is no need 
>>> for fix in ImageIO.read() methods as null stream is handled in 
>>> read(ImageInputStream stream) which is called by all the remaining read() 
>>> API's through IAE. So i can remove the changes made  in ImageIO.read() 
>>> functions. Also istream is closed in finally block of read(url).
>>>
>>>              For ImageIO.write(File) &  ImageIO.write(OutputStream) NPE we 
>>> have two approaches for fix:
>>>
>>>              1) Keep the present changes of throwing IOException when 
>>> stream is null and change the throw clause of write() spec mentioning:
>>>
>>>                    "IOException - if an error occurs during writing or not 
>>> able to create required ImageOutputStream"
>>>
>>>              2) Remove the present changes and handle null in doWrite() 
>>> method by returning false when stream is null & add code in finally block 
>>> to close the stream      only when stream is not null. Along with this we 
>>> can also change Returns clause of spec to mention that write() might return 
>>> false when we are not      able to create ImageOutputStream.
>>>
>>>
>>>
>>>                        private static boolean doWrite(RenderedImage 
>>> im, ImageWriter writer,
>>>
>>>
>>> ImageOutputStream output) throws IOException {
>>>
>>>                                   if (writer == null) {
>>>
>>>                                                  return false;
>>>
>>>                                   }
>>>
>>>                                   + if (output == null) {
>>>
>>>                                           +       return false;
>>>
>>>                                   + }
>>>
>>>
>>>
>>>                            try {
>>>
>>>                                               return doWrite(im, 
>>> writer, stream);
>>>
>>>                                    } finally {
>>>
>>>                                            + if (stream != null)
>>>
>>>                                        stream.close();
>>>
>>>                                    }
>>>
>>>
>>>
>>>                    Returns :
>>>
>>>                            false if no appropriate writer is found or not 
>>> able to create required ImageOutputStream.
>>>
>>>              Please let me know your inputs.
>>>
>>>              Thanks,
>>>
>>>              Jay
>>>
>>>              -----Original Message-----
>>>
>>>              From: Sergey Bylokhov
>>>
>>>              Sent: Friday, March 18, 2016 12:24 AM
>>>
>>>              To: Jayathirth D V
>>>
>>>              Cc:2d-dev@openjdk.java.net 
>>> <mailto:2d-dev@openjdk.java.net>; Philip Race
>>>
>>>              Subject: Re: [OpenJDK 2D-Dev] Review Request for
>>> JDK-8044289 : In
>>>
>>>              ImageIO.read() and write() NPE is not handled properly 
>>> for stream
>>>
>>>              On 17.03.16 21:14, Jayathirth D V wrote:
>>>
>>>                  There are many places in createImageInputStream() and 
>>> createImageOutputStream() where it will return null for stream.
>>>
>>>              But when why you change the write/read methods? They should 
>>> take null into account and work according to specification. If some bogus 
>>> null returns from createImageInputStream/createImageOutputStream then it 
>>> should be fixed in these methods.
>>>
>>>                  So for NPE described in bug to occur there can be multiple 
>>> paths:
>>>
>>>                  1) One of the path described in bug is when 
>>> theRegistry.getServiceProviders() throws IAE and we return null.
>>>
>>>              This is the case when we have no installed spi and should 
>>> return null/false.
>>>
>>>                  2) When we pass non-existent file path to ImageIO (as 
>>> described 
>>> inhttp://stackoverflow.com/questions/11153200/with-imageio-write-api-call-i-get-nullpointerexception
>>>   ). Here we catch FileNotFoundException but still we return stream as null 
>>> at the end which will cause NPE further.
>>>
>>>              This is same thing described in the bug(about stream.close()). 
>>> The write method call createImageOutputStream() and got 
>>> FileNotFoundException.
>>>
>>>              This exception should be propagated to the user, but it is 
>>> replaced in the finally block, because we try to close the stream=null. So 
>>> the fix for this particular case is to check the stream to null in finally, 
>>> No?
>>>
>>>                  3) When we don't support the provider and 
>>> theRegistry.getServiceProviders() return iterator with size zero.
>>>
>>>              This means that our providers do not support this case, and we 
>>> should return null/false.
>>>
>>>                  For us to follow first scenario we need access to 
>>> categoryMap of IIORegistry and delete the ImageInputStreamSpi/ 
>>> ImageOutputStreamSpi but I was not able to find a way to tamper it from 
>>> test case. If we follow second case FileNotFoundException will be thrown by 
>>> default eventhough we handle NPE.
>>>
>>>              But you change the code and we now contradicts the 
>>> specification, in your case the test should expect false/null from 
>>> write()/read().
>>>
>>>                  In the test case we are trying to following third scenario 
>>> to get stream as null to verify the code changes.
>>>
>>>              To catch the bogus null we should try to use another approach, 
>>> or change the spec. But it seems all null values above are correct, we 
>>> should be ready for them.
>>>
>>>                  As part of collective fix we are throwing IOException 
>>> which will indicate that we are not able to create required stream.
>>>
>>>                  Thanks,
>>>
>>>                  Jay
>>>
>>>                  -----Original Message-----
>>>
>>>                  From: Sergey Bylokhov
>>>
>>>                  Sent: Thursday, March 17, 2016 7:27 PM
>>>
>>>                  To: Phil Race
>>>
>>>                  Cc: Jayathirth D V;2d-dev@openjdk.java.net 
>>> <mailto:2d-dev@openjdk.java.net>
>>>
>>>                  Subject: Re: [OpenJDK 2D-Dev] Review Request for
>>> JDK-8044289 : In
>>>
>>>                  ImageIO.read() and write() NPE is not handled 
>>> properly for stream
>>>
>>>                  On 17.03.16 0:36, Phil Race wrote:
>>>
>>>                      I don't think that is the actual reason here
>>>
>>>                  But the test doing exactly this thing -> deregister 
>>> all spi => in
>>>
>>>                  this case according to specification all related
>>>
>>>                  
>>> methods(read/write/creatImageInputStream/creatImageOutputStream) should 
>>> return null or false.
>>>
>>>                  - it seems likely that there
>>>
>>>                      was some kind of internal error or bad SPI causing 
>>> this.
>>>
>>>                      So throwing an exception seems more appropriate.
>>>
>>>                  the problem was in some of our methods which do not expect 
>>> null in some places(like stream.close() from the bug description).
>>>
>>>                      And also the bug was originally solely about write(..).
>>>
>>>                      -phil.
>>>
>>>                      On 03/16/2016 01:35 PM, Sergey Bylokhov wrote:
>>>
>>>                          As far as I understand the
>>> createImageInputStream() returns null
>>>
>>>                          is this stream is unsupported by current 
>>> plugins via spi. Probably
>>>
>>>                          the
>>>
>>>                          read() method should return null too?
>>>
>>>                                  /**
>>>
>>>                                   * Returns a {@code BufferedImage} 
>>> as the result of decoding
>>>
>>>                                   * a supplied {@code InputStream} 
>>> with an {@code ImageReader}
>>>
>>>                                   * chosen automatically from among those 
>>> currently registered.
>>>
>>>                                   * The {@code InputStream} is 
>>> wrapped in an
>>>
>>>                                   * {@code ImageInputStream}.  If no 
>>> registered
>>>
>>>                                   * {@code ImageReader} claims to be 
>>> able to read the
>>>
>>>                                   * resulting stream, {@code null} is 
>>> returned.
>>>
>>>                                   *
>>>
>>>                          .......
>>>
>>>                                   * @return a {@code BufferedImage} 
>>> containing the decoded
>>>
>>>                                   * contents of the input, or {@code null}.
>>>
>>>                                   */
>>>
>>>                                  public static BufferedImage 
>>> read(InputStream input) throws
>>>
>>>                          IOException
>>>
>>>                          On 16.03.16 20:29, Philip Race wrote:
>>>
>>>                              The test writes out into "test.src".
>>>
>>>                              I believe that you should treat that as a 
>>> "read-only" location.
>>>
>>>                              Write to a tempfile (File.createTempFile()) or 
>>> TESTCLASSES.
>>>
>>>                              -phil.
>>>
>>>                              On 3/15/16, 10:50 PM, Jayathirth D V wrote:
>>>
>>>                                  Hi Phil,All
>>>
>>>                                  _Please review the following fix in 
>>> JDK9:_
>>>
>>>                                  __
>>>
>>>                                  Bug
>>> :https://bugs.openjdk.java.net/browse/JDK-8044289
>>>
>>>                                  Webrev 
>>> :http://cr.openjdk.java.net/~jdv/8044289/webrev.00/
>>>
>>> <http://cr.openjdk.java.net/%7Ejdv/8044289/webrev.00/>
>>>
>>>                                  
>>> <http://cr.openjdk.java.net/%7Ejdv/8044289/webrev.00/>
>>>
>>> <http://cr.openjdk.java.net/%7Ejdv/8044289/webrev.00/>
>>>
>>>                                  Issue : When 
>>> createImageInputStream() or createImageOutputStream
>>>
>>>                                  returns null in ImageIO.read() or
>>> ImageIO.write() we are seeing
>>>
>>>                                  NPE as it stream is used further without 
>>> null check.
>>>
>>>                                  Root cause : "stream" is used 
>>> without checking whether it is
>>>
>>>                                  null or not.
>>>
>>>                                  Solution : Handle null pointer of stream 
>>> and throw IIOException.
>>>
>>>                                  Test case contains all possible 
>>> scenarios where
>>>
>>>                                  createImageInputStream() or 
>>> createImageOutputStream can return null.
>>>
>>>                                  Thanks,
>>>
>>>                                  Jay
>>>
>>>                  --
>>>
>>>                  Best regards, Sergey.
>>>
>>>              --
>>>
>>>              Best regards, Sergey.
>>>
>>>          --
>>>
>>>          Best regards, Sergey.
>>>
>>>      --
>>>
>>>      Best regards, Sergey.
>>>
>
>
> --
> Best regards, Sergey.
>


--
Best regards, Sergey.

Reply via email to