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

fix: use opj_uint_ceildiv instead of opj_int_ceildiv when necessary #1482

Merged
merged 2 commits into from
Sep 23, 2023

Conversation

mayeut
Copy link
Collaborator

@mayeut mayeut commented Sep 23, 2023

There are a bunch of loc where we can see a usage of opj_int_ceildiv:

(OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)a, (OPJ_INT32)b);

where a & b are OPJ_UINT32.

This can lead to overflow/underflow for some a/b combinations.
Replace those calls by opj_uint_ceildiv instead to always get a correct result.

This also allows some valid single tile images with huge tile size to be decoded properly.
Fix #1438

Requires data from uclouvain/openjpeg-data#24

mayeut added a commit to mayeut/openjpeg-data that referenced this pull request Sep 23, 2023
rouault added a commit to uclouvain/openjpeg-data that referenced this pull request Sep 23, 2023
@rouault
Copy link
Collaborator

rouault commented Sep 23, 2023

can you git commit --amend & git push -f to force CI to restart now that uclouvain/openjpeg-data#24 has been merged ?

There are a bunch of loc where we can see a usage of `opj_int_ceildiv`:
```
(OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)a, (OPJ_INT32)b);
```
where a & b are `OPJ_UINT32`.

This can lead to overflow/underflow for some a/b combinations.
Replace those calls by `opj_uint_ceildiv` instead to always get a correct result.

This also allows some valid single tile images with huge tile size to be decoded properly.
Fix uclouvain#1438
@mayeut
Copy link
Collaborator Author

mayeut commented Sep 23, 2023

I'm seeing the same tests failures for "regular" on master in my fork: https://github.com/mayeut/openjpeg/actions/runs/6278478237/job/17052321449

Not sure how to go forward.

@rouault
Copy link
Collaborator

rouault commented Sep 23, 2023

Not sure how to go forward.

maybe try renaming the existing tools/travis-ci/knownfailures-Ubuntu22.04-gcc11.3.0-x86_64-Release-3rdP.txt file as tools/travis-ci/knownfailures-Ubuntu22.04-gcc11.4.0-x86_64-Release-3rdP.txt since there's appear to have been an upgrade from gcc 11.3 to 11.4

@rouault rouault merged commit 6af3931 into uclouvain:master Sep 23, 2023
12 checks passed
@mayeut mayeut deleted the use-opj_uint_ceildiv branch September 23, 2023 13:27
@Jamaika1
Copy link
Contributor

Jamaika1 commented Sep 24, 2023

Why do I need to use OPJ_HAVE_INTTYPES_H for GCC Windows?

j2k.c: In function 'opj_j2k_dump_MH_info':
j2k.c:11341:35: error: expected ')' before 'PRIu32'
11341 |     fprintf(out_stream, "\t tx0=%" PRIu32 ", ty0=%" PRIu32 "\n", p_j2k->m_cp.tx0,
      |            ~                      ^~~~~~~
      |                                   )
j2k.c:45:1: note: 'PRIu32' is defined in header '<inttypes.h>'; did you forget to '#include <inttypes.h>'?
   44 | #include "opj_includes.h"
  +++ |+#include <inttypes.h>
   45 |
j2k.c:11343:35: error: expected ')' before 'PRIu32'
11343 |     fprintf(out_stream, "\t tdx=%" PRIu32 ", tdy=%" PRIu32 "\n", p_j2k->m_cp.tdx,
      |            ~                      ^~~~~~~
      |                                   )
j2k.c:11343:36: note: 'PRIu32' is defined in header '<inttypes.h>'; did you forget to '#include <inttypes.h>'?
11343 |     fprintf(out_stream, "\t tdx=%" PRIu32 ", tdy=%" PRIu32 "\n", p_j2k->m_cp.tdx,
      |                                    ^~~~~~
j2k.c:11345:34: error: expected ')' before 'PRIu32'
11345 |     fprintf(out_stream, "\t tw=%" PRIu32 ", th=%" PRIu32 "\n", p_j2k->m_cp.tw,
      |            ~                     ^~~~~~~
      |                                  )
j2k.c:11345:35: note: 'PRIu32' is defined in header '<inttypes.h>'; did you forget to '#include <inttypes.h>'?
11345 |     fprintf(out_stream, "\t tw=%" PRIu32 ", th=%" PRIu32 "\n", p_j2k->m_cp.tw,
      |                                   ^~~~~~

@rouault
Copy link
Collaborator

rouault commented Sep 24, 2023

@Jamaika1 does #1483 do the job ?

@mayeut
Copy link
Collaborator Author

mayeut commented Sep 24, 2023

@rouault,

with #1450 (which goes with "Remove support for non-C99 compilers (like VS2010) that don't support snprintf()"), support for MSVC versions prior to vs2015 is dropped (https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010).

This means that all supported MSVC versions do have stdint.h & inttypes.h now.
For non windows platforms, those headers were mandatory.

I can either add a definition for PRIu32 in the current opj_inttypes.h or just make those headers mandatory altogether.

I'd rather go with the second option.

Any thoughts ?

@rouault
Copy link
Collaborator

rouault commented Sep 24, 2023

I'd rather go with the second option.

ah yes, but @Jamaika1 how come inttypes.h isn't detected on your gcc windows ? Are you using an antiquated version ?

@mayeut
Copy link
Collaborator Author

mayeut commented Sep 24, 2023

@Jamaika1, were you defining -DOPJ_HAVE_INTTYPES_H=0 in your cmake configure step rather than letting cmake find/define those ?

@Jamaika1
Copy link
Contributor

Jamaika1 commented Sep 24, 2023

I'm amateur who decided to manually assemble ffmpeg in gcc. There are lot of additions and bugs.
https://github.com/Jamaika1/plugins_ffmpeg_vvc_evc_htj2k
I use c/c++11.
I have this record:
As I understand it, in mingw64 (no POSIX) I should not use inttypes.h, sys/types.h, sys/types.h, sys/stat.h

#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
#include <stdint.h>

   typedef int16_t celt_int16;
   typedef uint16_t celt_uint16;
   typedef int32_t celt_int32;
   typedef uint32_t celt_uint32;
#elif defined(_WIN32) 

#  if defined(__CYGWIN__)
#    include <_G_config.h>
     typedef _G_int32_t celt_int32;
     typedef _G_uint32_t celt_uint32;
     typedef _G_int16 celt_int16;
     typedef _G_uint16 celt_uint16;
#  elif defined(__MINGW32__)
     typedef short celt_int16;
     typedef unsigned short celt_uint16;
     typedef int celt_int32;
     typedef unsigned int celt_uint32;
#  elif defined(__MWERKS__)
     typedef int celt_int32;
     typedef unsigned int celt_uint32;
     typedef short celt_int16;
     typedef unsigned short celt_uint16;
#  else
     /* MSVC/Borland */
     typedef __int32 celt_int32;
     typedef unsigned __int32 celt_uint32;
     typedef __int16 celt_int16;
     typedef unsigned __int16 celt_uint16;
#  endif

#elif defined(__MACOS__)

#  include <sys/types.h>
   typedef SInt16 celt_int16;
   typedef UInt16 celt_uint16;
   typedef SInt32 celt_int32;
   typedef UInt32 celt_uint32;

#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */

#  include <sys/types.h>
   typedef int16_t celt_int16;
   typedef u_int16_t celt_uint16;
   typedef int32_t celt_int32;
   typedef u_int32_t celt_uint32;

#elif defined(__BEOS__)

   /* Be */
#  include <inttypes.h>
   typedef int16 celt_int16;
   typedef u_int16 celt_uint16;
   typedef int32_t celt_int32;
   typedef u_int32_t celt_uint32;

#else 

@rouault
Copy link
Collaborator

rouault commented Sep 24, 2023

in mingw64 (no POSIX) I should not use inttypes.h

inttypes.h is a standard headers that all C99 and C++11 compatible compilers (including mingw64) should provide

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.

Integer Overflow in src/lib/openjp2/image.c
3 participants