CVE-2021-46389 (C++, published 2022-02-07T14:15Z)
Description: value: IIPImage High Resolution Streaming Image Server prior to commit 882925b295a80ec992063deffc2a3b0d803c3195 is affected by an integer overflow in iipsrv.fcgi through malformed HTTP query parameters.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-190 \u2014 Integer Overflow or Wraparound
The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
Repository: https://github.com/ruven/iipsrv
Files changed:
ChangeLog
src/JTL.cc
src/SPECTRA.cc
Commit message: Added verification that image has been set in SPECTRA.cc and check on the validity of the requested tile resolution in JTL.cc. Fixes a couple of the crash conditions reported in https://github.com/ruven/iipsrv/issues/223


Vulnerable code:
    Copyright (C) 2006-2021 Ruven Pillay.
    int num_res = (*session->image)->getNumResolutions();
  if( (resolution<0) || (tile<0) ){
  int num_res = (*session->image)->getNumResolutions();
  unsigned int im_width = (*session->image)->image_widths[num_res-resolution-1];
  unsigned int im_height = (*session->image)->image_heights[num_res-resolution-1];
  float dpi_x = (*session->image)->dpi_x * (float) im_width / (float) (*session->image)->getImageWidth();
  float dpi_y = (*session->image)->dpi_y * (float) im_height / (float) (*session->image)->getImageHeight();
  compressor->setResolution( dpi_x, dpi_y, (*session->image)->dpi_units );

  if( session->loglevel >= 5 ){
    *(session->logfile) << "JTL :: Setting physical resolution of tile to " <<  dpi_x << " x " << dpi_y
                        << ( ((*session->image)->dpi_units==1) ? " pixels/inch" : " pixels/cm" ) << endl;
    Copyright (C) 2009-2021 Ruven Pillay.
  int resolution, tile, x, y;
  resolution = atoi( arg.substr(0,delimitter).c_str() );
  tile = atoi( arg.substr(0,delimitter).c_str() );
  x = atoi( arg.substr(0,delimitter).c_str() );
  y = atoi( arg.substr(0,arg.length()).c_str() );

Fixed code:
15/01/2022:
	- Added verification that image has been set in SPECTRA.cc and check on the validity of the requested tile
	  resolution in JTL.cc. Fixes a couple of the crash conditions reported in https://github.com/ruven/iipsrv/issues/223


    Copyright (C) 2006-2022 Ruven Pillay.
  // Need to know the number of resolutions
  int num_res = (*session->image)->getNumResolutions();


  if( (resolution<0) || (tile<0) || (resolution>=num_res) ){
  if( (*session->image)->dpi_x > 0 && (*session->image)->dpi_y > 0 ){
    unsigned int im_width = (*session->image)->image_widths[num_res-resolution-1];
    unsigned int im_height = (*session->image)->image_heights[num_res-resolution-1];
    float dpi_x = (*session->image)->dpi_x * ( (float)im_width / (float)(*session->image)->getImageWidth() );
    float dpi_y = (*session->image)->dpi_y * ( (float)im_height / (float)(*session->image)->getImageHeight() );
    compressor->setResolution( dpi_x, dpi_y, (*session->image)->dpi_units );

    if( session->loglevel >= 5 ){
      *(session->logfile) << "JTL :: Setting physical resolution of tile to " <<  dpi_x << " x " << dpi_y
			  << ( ((*session->image)->dpi_units==1) ? " pixels/inch" : " pixels/cm" ) << endl;
    }

    Copyright (C) 2009-2022 Ruven Pillay.

  // Make sure we have set our image
  this->session = session;
  checkImage();
  int resolution = atoi( arg.substr(0,delimitter).c_str() );
  int tile = atoi( arg.substr(0,delimitter).c_str() );
  int x = atoi( arg.substr(0,delimitter).c_str() );
  int y = atoi( arg.substr(0,arg.length()).c_str() );