@@ -251,6 +251,7 @@ static float fMAX(float a, float b)
251251 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B
252252 */
253253
254+ #define RAWINDEX(row, col) ((row)*raw_width + (col))
254255#define RAW(row,col) \
255256 raw_image[(row)*raw_width+(col)]
256257//@end DEFINES
@@ -1511,9 +1512,14 @@ void CLASS pentax_load_raw()
15111512
15121513void CLASS nikon_coolscan_load_raw()
15131514{
1514- int bufsize = width*3*tiff_bps/8;
1515- if(tiff_bps <= 8)
1516- gamma_curve(1.0/imgdata.params.coolscan_nef_gamma,0.,1,255);
1515+ if(!image)
1516+ throw LIBRAW_EXCEPTION_IO_CORRUPT;
1517+
1518+ int bypp = tiff_bps <= 8 ? 1 : 2;
1519+ int bufsize = width * 3 * bypp;
1520+
1521+ if (tiff_bps <= 8)
1522+ gamma_curve(1.0 / imgdata.params.coolscan_nef_gamma, 0., 1, 255);
15171523 else
15181524 gamma_curve(1.0/imgdata.params.coolscan_nef_gamma,0.,1,65535);
15191525 fseek (ifp, data_offset, SEEK_SET);
@@ -1794,7 +1800,12 @@ void CLASS rollei_thumb()
17941800void CLASS rollei_load_raw()
17951801{
17961802 uchar pixel[10];
1797- unsigned iten=0, isix, i, buffer=0, todo[16];
1803+ unsigned iten = 0, isix, i, buffer = 0, todo[16];
1804+ #ifdef LIBRAW_LIBRARY_BUILD
1805+ if(raw_width > 32767 || raw_height > 32767)
1806+ throw LIBRAW_EXCEPTION_IO_BADFILE;
1807+ #endif
1808+ unsigned maxpixel = raw_width*(raw_height+7);
17981809
17991810 isix = raw_width * raw_height * 5 / 8;
18001811 while (fread (pixel, 1, 10, ifp) == 10) {
@@ -1810,8 +1821,11 @@ void CLASS rollei_load_raw()
18101821 todo[i] = isix++;
18111822 todo[i+1] = buffer >> (14-i)*5;
18121823 }
1813- for (i=0; i < 16; i+=2)
1814- raw_image[todo[i]] = (todo[i+1] & 0x3ff);
1824+ for (i = 0; i < 16; i += 2)
1825+ if(todo[i] < maxpixel)
1826+ raw_image[todo[i]] = (todo[i + 1] & 0x3ff);
1827+ else
1828+ derror();
18151829 }
18161830 maximum = 0x3ff;
18171831}
@@ -3857,6 +3871,11 @@ void CLASS sony_arw2_load_raw()
38573871void CLASS samsung_load_raw()
38583872{
38593873 int row, col, c, i, dir, op[4], len[4];
3874+ #ifdef LIBRAW_LIBRARY_BUILD
3875+ if(raw_width> 32768 || raw_height > 32768) // definitely too much for old samsung
3876+ throw LIBRAW_EXCEPTION_IO_BADFILE;
3877+ #endif
3878+ unsigned maxpixels = raw_width*(raw_height+7);
38603879
38613880 order = 0x4949;
38623881 for (row=0; row < raw_height; row++) {
@@ -3875,11 +3894,17 @@ void CLASS samsung_load_raw()
38753894 case 2: len[c]--; break;
38763895 case 1: len[c]++;
38773896 }
3878- for (c=0; c < 16; c+=2) {
3879- i = len[((c & 1) << 1) | (c >> 3)];
3880- RAW(row,col+c) = ((signed) ph1_bits(i) << (32-i) >> (32-i)) +
3881- (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128);
3882- if (c == 14) c = -1;
3897+ for (c = 0; c < 16; c += 2)
3898+ {
3899+ i = len[((c & 1) << 1) | (c >> 3)];
3900+ unsigned idest = RAWINDEX(row, col + c);
3901+ unsigned isrc = (dir ? RAWINDEX(row + (~c | -2), col + c) : col ? RAWINDEX(row, col + (c | -2)) : 0);
3902+ if(idest < maxpixels && isrc < maxpixels) // less than zero is handled by unsigned conversion
3903+ RAW(row, col + c) = ((signed)ph1_bits(i) << (32 - i) >> (32 - i)) + (dir ? RAW(row + (~c | -2), col + c) : col ? RAW(row, col + (c | -2)) : 128);
3904+ else
3905+ derror();
3906+ if (c == 14)
3907+ c = -1;
38833908 }
38843909 }
38853910 }
@@ -11081,37 +11106,68 @@ void CLASS parse_exif (int base)
1108111106 if (((make[0] == '\0') && (!strncmp(model, "ov5647",6))) ||
1108211107 ((!strncmp(make, "RaspberryPi",11)) && (!strncmp(model, "RP_OV5647",9))) ||
1108311108 ((!strncmp(make, "RaspberryPi",11)) && (!strncmp(model, "RP_imx219",9)))) {
11084- char mn_text[512];
11085- char* pos;
11086- char ccms[512];
11087- ushort l;
11088- float num;
11089-
11090- fgets(mn_text, len, ifp);
11091- pos = strstr(mn_text, "gain_r=");
11092- if (pos) cam_mul[0] = atof(pos+7);
11093- pos = strstr(mn_text, "gain_b=");
11094- if (pos) cam_mul[2] = atof(pos+7);
11095- if ((cam_mul[0] > 0.001f) && (cam_mul[2] > 0.001f)) cam_mul[1] = cam_mul[3] = 1.0f;
11096- else cam_mul[0] = cam_mul[2] = 0.0f;
11097-
11098- pos = strstr(mn_text, "ccm=") + 4;
11099- l = strstr(pos, " ") - pos;
11100- memcpy (ccms, pos, l);
11101- ccms[l] = '\0';
11102-
11103- pos = strtok (ccms, ",");
11104- for (l=0; l<4; l++) {
11105- num = 0.0;
11106- for (c=0; c<3; c++) {
11107- imgdata.color.ccm[l][c] = (float)atoi(pos);
11108- num += imgdata.color.ccm[l][c];
11109- pos = strtok (NULL, ",");
11110- }
11111- if (num > 0.01) FORC3 imgdata.color.ccm[l][c] = imgdata.color.ccm[l][c] / num;
11112- }
11109+ char mn_text[512];
11110+ char *pos;
11111+ char ccms[512];
11112+ ushort l;
11113+ float num;
11114+
11115+ fgets(mn_text, MIN(len,511), ifp);
11116+ mn_text[511] = 0;
11117+
11118+ pos = strstr(mn_text, "gain_r=");
11119+ if (pos)
11120+ cam_mul[0] = atof(pos + 7);
11121+ pos = strstr(mn_text, "gain_b=");
11122+ if (pos)
11123+ cam_mul[2] = atof(pos + 7);
11124+ if ((cam_mul[0] > 0.001f) && (cam_mul[2] > 0.001f))
11125+ cam_mul[1] = cam_mul[3] = 1.0f;
11126+ else
11127+ cam_mul[0] = cam_mul[2] = 0.0f;
11128+
11129+ pos = strstr(mn_text, "ccm=");
11130+ if(pos)
11131+ {
11132+ pos +=4;
11133+ char *pos2 = strstr(pos, " ");
11134+ if(pos2)
11135+ {
11136+ l = pos2 - pos;
11137+ memcpy(ccms, pos, l);
11138+ ccms[l] = '\0';
11139+ #if defined WIN32 || defined(__MINGW32__)
11140+ // Win32 strtok is already thread-safe
11141+ pos = strtok(ccms, ",");
11142+ #else
11143+ char *last=0;
11144+ pos = strtok_r(ccms, ",",&last);
11145+ #endif
11146+ if(pos)
11147+ {
11148+ for (l = 0; l < 4; l++)
11149+ {
11150+ num = 0.0;
11151+ for (c = 0; c < 3; c++)
11152+ {
11153+ imgdata.color.ccm[l][c] = (float)atoi(pos);
11154+ num += imgdata.color.ccm[l][c];
11155+ #if defined WIN32 || defined(__MINGW32__)
11156+ pos = strtok(NULL, ",");
11157+ #else
11158+ pos = strtok_r(NULL, ",",&last);
11159+ #endif
11160+ if(!pos) goto end; // broken
11161+ }
11162+ if (num > 0.01)
11163+ FORC3 imgdata.color.ccm[l][c] = imgdata.color.ccm[l][c] / num;
11164+ }
11165+ }
11166+ }
1111311167 }
11114- else
11168+ end:;
11169+ }
11170+ else
1111511171#endif
1111611172 parse_makernote (base, 0);
1111711173 break;
@@ -15077,7 +15133,8 @@ float CLASS find_green (int bps, int bite, int off0, int off1)
1507715133 UINT64 bitbuf=0;
1507815134 int vbits, col, i, c;
1507915135 ushort img[2][2064];
15080- double sum[]={0,0};
15136+ double sum[] = {0, 0};
15137+ if(width > 2064) return 0.f; // too wide
1508115138
1508215139 FORC(2) {
1508315140 fseek (ifp, c ? off1:off0, SEEK_SET);
@@ -15100,14 +15157,16 @@ float CLASS find_green (int bps, int bite, int off0, int off1)
1510015157#ifdef LIBRAW_LIBRARY_BUILD
1510115158static void remove_trailing_spaces(char *string, size_t len)
1510215159{
15103- if(len<1) return; // not needed, b/c sizeof of make/model is 64
15104- string[len-1]=0;
15105- if(len<3) return; // also not needed
15106- len = strnlen(string,len-1);
15107- for(int i=len-1; i>=0; i--)
15160+ if (len < 1)
15161+ return; // not needed, b/c sizeof of make/model is 64
15162+ string[len - 1] = 0;
15163+ if (len < 3)
15164+ return; // also not needed
15165+ len = strnlen(string, len - 1);
15166+ for (int i = len - 1; i >= 0; i--)
1510815167 {
15109- if(isspace(string[i]))
15110- string[i]= 0;
15168+ if (isspace((unsigned char) string[i]))
15169+ string[i] = 0;
1511115170 else
1511215171 break;
1511315172 }
0 commit comments