text:   static FT_Error
    CVE_2014_9656_VULN_tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
                                FT_UInt         glyph_index,
                                FT_Int          x_pos,
                                FT_Int          y_pos )
    {
      /*
       *  First, we find the correct strike range that applies to this
       *  glyph index.
       */
  
      FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;
      FT_Byte*  p_limit    = decoder->eblc_limit;
      FT_ULong  num_ranges = decoder->strike_index_count;
      FT_UInt   start, end, index_format, image_format;
      FT_ULong  image_start = 0, image_end = 0, image_offset;
  
  
      for ( ; num_ranges > 0; num_ranges-- )
      {
        start = FT_NEXT_USHORT( p );
        end   = FT_NEXT_USHORT( p );
  
        if ( glyph_index >= start && glyph_index <= end )
          goto FoundRange;
  
        p += 4;  /* ignore index offset */
      }
      goto NoBitmap;
  
    FoundRange:
      image_offset = FT_NEXT_ULONG( p );
  
      /* overflow check */
      p = decoder->eblc_base + decoder->strike_index_array;
      if ( image_offset > (FT_ULong)( p_limit - p ) )
        goto Failure;
  
      p += image_offset;
      if ( p + 8 > p_limit )
        goto NoBitmap;
  
      /* now find the glyph's location and extend within the ebdt table */
      index_format = FT_NEXT_USHORT( p );
      image_format = FT_NEXT_USHORT( p );
      image_offset = FT_NEXT_ULONG ( p );
  
      switch ( index_format )
      {
      case 1: /* 4-byte offsets relative to `image_offset' */
        p += 4 * ( glyph_index - start );
        if ( p + 8 > p_limit )
          goto NoBitmap;
  
        image_start = FT_NEXT_ULONG( p );
        image_end   = FT_NEXT_ULONG( p );
  
        if ( image_start == image_end )  /* missing glyph */
          goto NoBitmap;
        break;
  
      case 2: /* big metrics, constant image size */
        {
          FT_ULong  image_size;
  
  
          if ( p + 12 > p_limit )
            goto NoBitmap;
  
          image_size = FT_NEXT_ULONG( p );
  
          if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
            goto NoBitmap;
  
          image_start = image_size * ( glyph_index - start );
          image_end   = image_start + image_size;
        }
        break;
  
      case 3: /* 2-byte offsets relative to 'image_offset' */
        p += 2 * ( glyph_index - start );
        if ( p + 4 > p_limit )
          goto NoBitmap;
  
        image_start = FT_NEXT_USHORT( p );
        image_end   = FT_NEXT_USHORT( p );
  
        if ( image_start == image_end )  /* missing glyph */
          goto NoBitmap;
        break;
  
      case 4: /* sparse glyph array with (glyph,offset) pairs */
        {
          FT_ULong  mm, num_glyphs;
  
  
          if ( p + 4 > p_limit )
            goto NoBitmap;
  
          num_glyphs = FT_NEXT_ULONG( p );
  
          /* overflow check for p + ( num_glyphs + 1 ) * 4 */
          if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
            goto NoBitmap;
  
          for ( mm = 0; mm < num_glyphs; mm++ )
          {
            FT_UInt  gindex = FT_NEXT_USHORT( p );
  
  
            if ( gindex == glyph_index )
            {
              image_start = FT_NEXT_USHORT( p );
              p          += 2;
              image_end   = FT_PEEK_USHORT( p );
              break;
            }
            p += 2;
          }
  
          if ( mm >= num_glyphs )
            goto NoBitmap;
        }
        break;
  
      case 5: /* constant metrics with sparse glyph codes */
      case 19:
        {
          FT_ULong  image_size, mm, num_glyphs;
  
  
          if ( p + 16 > p_limit )
            goto NoBitmap;
  
          image_size = FT_NEXT_ULONG( p );
  
          if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
            goto NoBitmap;
  
          num_glyphs = FT_NEXT_ULONG( p );
  
          /* overflow check for p + 2 * num_glyphs */
          if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) )
            goto NoBitmap;
  
          for ( mm = 0; mm < num_glyphs; mm++ )
          {
            FT_UInt  gindex = FT_NEXT_USHORT( p );
  
  
            if ( gindex == glyph_index )
              break;
          }
  
          if ( mm >= num_glyphs )
            goto NoBitmap;
  
          image_start = image_size * mm;
          image_end   = image_start + image_size;
        }
        break;
  
      default:
        goto NoBitmap;
      }
  
      if ( image_start > image_end )
        goto NoBitmap;
  
      image_end  -= image_start;
      image_start = image_offset + image_start;
  
      FT_TRACE3(( "CVE_2014_9656_VULN_tt_sbit_decoder_load_image:"
                  " found sbit (format %d) for glyph index %d\n",
                  image_format, glyph_index ));
  
      return tt_sbit_decoder_load_bitmap( decoder,
                                          image_format,
                                          image_start,
                                          image_end,
                                          x_pos,
                                          y_pos );
  
    Failure:
      return FT_THROW( Invalid_Table );
  
    NoBitmap:
      FT_TRACE4(( "CVE_2014_9656_VULN_tt_sbit_decoder_load_image:"
                  " no sbit found for glyph index %d\n", glyph_index ));
  
      return FT_THROW( Invalid_Argument );
    }
  