Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pngrutil.c: Delete dead code in png_handle_PLTE() #484

Open
wants to merge 1 commit into
base: libpng16
Choose a base branch
from

Conversation

wantehchang
Copy link
Contributor

@wantehchang wantehchang commented Jun 23, 2023

Delete unreachable code in png_handle_PLTE() related to the condition #ifndef PNG_READ_OPT_PLTE_SUPPORTED.

Suppose PNG_READ_OPT_PLTE_SUPPORTED is not defined. If png_ptr->color_type is not PNG_COLOR_TYPE_PALETTE, the function has returned earlier in the function. So if we reach here, png_ptr->color_type must be PNG_COLOR_TYPE_PALETTE, therefore the if-else statement:

   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   {
      A;
   }
   else if (blah) {
      B;
   }

is equivalent to:

   A;

On the other hand, suppose PNG_READ_OPT_PLTE_SUPPORTED is defined. Then "if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)" and the entire "else if (blah) { B; }" are not compiled, leaving only "A;".

png_chunk_warning(png_ptr, "CRC error");
}
#endif
png_crc_finish(png_ptr, (png_uint_32) (length - (unsigned int)num * 3));
Copy link
Contributor Author

@wantehchang wantehchang Jun 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(1) Please check if the comment block at lines 1012-1016 should be updated.

(2) I assume there is no bug and therefore the unreachable code can be safely deleted. But perhaps there is a bug and the code should not be unreachable. So please check the code I deleted carefully.

Thanks!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are both "#ifndef".

Your logic seems to assume the second is "#ifdef"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirm they are both #ifndef. I did not assume the second is #ifdef.

Earlier in the function, at lines 952-958, we have:

#ifndef PNG_READ_OPT_PLTE_SUPPORTED
   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
   {
      png_crc_finish(png_ptr, length);
      return;
   }
#endif

Suppose #ifndef PNG_READ_OPT_PLTE_SUPPORTED is true. If we reach here, the png_ptr->color_type == PNG_COLOR_TYPE_PALETTE condition at line 1018 of the original code must be true, so the else if block at lines 1025-1048 of the original code will never be taken.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that the comment block at lines 1012-1016 describes the original code. So the comment block should be deleted (or updated) in this pull request.

@wantehchang
Copy link
Contributor Author

The early return from png_handle_PLTE() that I referred to is the folllowing:

 952 #ifndef PNG_READ_OPT_PLTE_SUPPORTED
 953    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
 954    {
 955       png_crc_finish(png_ptr, length);
 956       return;
 957    }
 958 #endif

Delete unreachable code in png_handle_PLTE() related to the
condition #ifndef PNG_READ_OPT_PLTE_SUPPORTED.

Suppose PNG_READ_OPT_PLTE_SUPPORTED is not defined. If
png_ptr->color_type is not PNG_COLOR_TYPE_PALETTE, the function has
returned earlier in the function. So if we reach here,
png_ptr->color_type must be PNG_COLOR_TYPE_PALETTE, therefore the
if-else statement:

   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
   {
      A;
   }
   else if (blah) {
      B;
   }

is equivalent to:

   A;

On the other hand, suppose PNG_READ_OPT_PLTE_SUPPORTED is defined. Then
"if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)" and the entire
"else if (blah) { B; }" are not compiled, leaving only "A;".
@jbowler
Copy link
Contributor

jbowler commented Nov 2, 2023

Are, that helps understanding. Those lines are clearly wrong for the reasons stated in the lines you want to remove; if READ_OPT_PLTE is unset (i.e. "don't read an optional palette") and the PLTE is optional (not a palette PNG) the code as written unconditionally errors out on a CRC error in the PLTE; pretty much the exact opposite of what is wanted. Easiest fix is just to delete those lines.

The actual code in there dates back to 1996/7 and it looks like the support for disabling reading of PLTE in non-palette PNGs never worked correctly.

@wantehchang since you are using the option to disable the PLTE read do you see any issues if you delete the erroneous lines? I.e. 952..958

@wantehchang
Copy link
Contributor Author

John: Thank you for taking a look. I am not familiar with libpng. (I remember I spotted this dead code while debugging #482.) I am afraid that I don't know the answer to your question.

I work on the Chrome web browser. Chrome undefines PNG_READ_OPT_PLTE_SUPPORTED in its third_party/libpng/pnglibconf.h file. I don't know why.

@jbowler
Copy link
Contributor

jbowler commented Nov 4, 2023

萬德 if my analysis is correct it's a bug anywhere. Since you are reporting bugs in Chrome:

https://chromium-review.googlesource.com/c/chromium/src/+/4616010

I suggest you report the spurious/dangerous exit before the error handling there. They should be able to test it and verify or refute my suggested change.

@wantehchang
Copy link
Contributor Author

wantehchang commented Nov 4, 2023

John: I just wrote a test Chrome changelist (patch) of your suggested change:
https://chromium-review.googlesource.com/c/chromium/src/+/5005531

I sent the changelist to Chrome's commit queue dry run. I will report back if it passes Chrome's test suite.

Did you suggest I report this bug in Chrome issue tracker? I can certainly do that, but isn't this a libpng bug? Or did you mean Chrome should not build libpng with PNG_READ_OPT_PLTE_SUPPORTED undefined?

@jbowler
Copy link
Contributor

jbowler commented Nov 4, 2023

I sent the changelist to Chrome's commit queue dry run. I will report back if it passes Chrome's test suite.

Yes, that's what I wanted. A full build test of libpng will, I'm fairly sure, just pass simply because it does not unset the option; so it proves nothing.

Did you suggest I report this bug in Chrome issue tracker? I can certainly do that, but isn't this a libpng bug? Or did you mean Chrome should not build libpng with PNG_READ_OPT_PLTE_SUPPORTED undefined?

It certainly looks like a bug in libpng; READ_OPT_PLTE isn't working correctly so far as I can see. I doubt it's an issue in Chrome because I believe Chrome turns off the CRC checking; that's a runtime option, "png_set_crc_action". Unfortunately the tests seem to be failing and they are failing in precisely the area of change.

@jbowler
Copy link
Contributor

jbowler commented Nov 4, 2023

Oh, it's the other bug you mentioned. Here's one of the results:

[ RUN      ] StaticPNGTests.ColorType2TrnsBeforePlte
../../third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc:1137: Failure
Value of: frame->HasAlpha()
  Actual: false
Expected: true

So, in fact, removing the erroneous code has actually fixed the other bug, but your tests are expecting the unfixed result!

Hah. Definitely an issue for Chrome :-) Seems like you will need to fix the tests first (it's not a very good test to test for the wrong answer :-)

EDIT: no, not necessarily; it's not clear if the Chrome tests ran with the fix for #482

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants