|
41 | 41 | #include "dSparse.h" |
42 | 42 | #include "eigs-base.h" |
43 | 43 | #include "lo-ieee.h" |
| 44 | +#include "lo-utils.h" |
44 | 45 | #include "lu.h" |
45 | 46 | #include "mx-ops.h" |
46 | 47 | #include "oct-error.h" |
@@ -915,9 +916,17 @@ EigsRealSymmetricMatrix (const M& m, const std::string typ, |
915 | 916 |
|
916 | 917 | F77_INT ido = 0; |
917 | 918 | int iter = 0; |
918 | | - F77_INT lwork = p * (p + 8); |
| 919 | + F77_INT elems; |
| 920 | + F77_INT lwork; |
919 | 921 |
|
920 | | - OCTAVE_LOCAL_BUFFER (double, v, n * p); |
| 922 | + if (octave::math::int_multiply_overflow (n, p, &elems)) |
| 923 | + (*current_liboctave_error_handler) |
| 924 | + ("eigs: array too large for Fortran integers"); |
| 925 | + if (octave::math::int_multiply_overflow (p, p + 8, &lwork)) |
| 926 | + (*current_liboctave_error_handler) |
| 927 | + ("eigs: array too large for Fortran integers"); |
| 928 | + |
| 929 | + OCTAVE_LOCAL_BUFFER (double, v, elems); |
921 | 930 | OCTAVE_LOCAL_BUFFER (double, workl, lwork); |
922 | 931 | OCTAVE_LOCAL_BUFFER (double, workd, 3 * n); |
923 | 932 | double *presid = resid.rwdata (); |
@@ -1190,9 +1199,17 @@ EigsRealSymmetricMatrixShift (const M& m, double sigma, |
1190 | 1199 | if (! LuAminusSigmaB (m, b, cholB, permB, sigma, L, U, P, Q, r)) |
1191 | 1200 | return -1; |
1192 | 1201 |
|
1193 | | - F77_INT lwork = p * (p + 8); |
| 1202 | + F77_INT elems; |
| 1203 | + F77_INT lwork; |
1194 | 1204 |
|
1195 | | - OCTAVE_LOCAL_BUFFER (double, v, n * p); |
| 1205 | + if (octave::math::int_multiply_overflow (n, p, &elems)) |
| 1206 | + (*current_liboctave_error_handler) |
| 1207 | + ("eigs: array too large for Fortran integers"); |
| 1208 | + if (octave::math::int_multiply_overflow (p, p + 8, &lwork)) |
| 1209 | + (*current_liboctave_error_handler) |
| 1210 | + ("eigs: array too large for Fortran integers"); |
| 1211 | + |
| 1212 | + OCTAVE_LOCAL_BUFFER (double, v, elems); |
1196 | 1213 | OCTAVE_LOCAL_BUFFER (double, workl, lwork); |
1197 | 1214 | OCTAVE_LOCAL_BUFFER (double, workd, 3 * n); |
1198 | 1215 | double *presid = resid.rwdata (); |
@@ -1533,9 +1550,17 @@ EigsRealSymmetricFunc (EigsFunc fcn, octave_idx_type n_arg, |
1533 | 1550 |
|
1534 | 1551 | F77_INT ido = 0; |
1535 | 1552 | int iter = 0; |
1536 | | - F77_INT lwork = p * (p + 8); |
| 1553 | + F77_INT elems; |
| 1554 | + F77_INT lwork; |
| 1555 | + |
| 1556 | + if (octave::math::int_multiply_overflow (n, p, &elems)) |
| 1557 | + (*current_liboctave_error_handler) |
| 1558 | + ("eigs: array too large for Fortran integers"); |
| 1559 | + if (octave::math::int_multiply_overflow (p, p + 8, &lwork)) |
| 1560 | + (*current_liboctave_error_handler) |
| 1561 | + ("eigs: array too large for Fortran integers"); |
1537 | 1562 |
|
1538 | | - OCTAVE_LOCAL_BUFFER (double, v, n * p); |
| 1563 | + OCTAVE_LOCAL_BUFFER (double, v, elems); |
1539 | 1564 | OCTAVE_LOCAL_BUFFER (double, workl, lwork); |
1540 | 1565 | OCTAVE_LOCAL_BUFFER (double, workd, 3 * n); |
1541 | 1566 | double *presid = resid.rwdata (); |
@@ -1889,9 +1914,17 @@ EigsRealNonSymmetricMatrix (const M& m, const std::string typ, |
1889 | 1914 |
|
1890 | 1915 | F77_INT ido = 0; |
1891 | 1916 | int iter = 0; |
1892 | | - F77_INT lwork = 3 * p * (p + 2); |
| 1917 | + F77_INT elems; |
| 1918 | + F77_INT lwork; |
1893 | 1919 |
|
1894 | | - OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1)); |
| 1920 | + if (octave::math::int_multiply_overflow (n, p + 1, &elems)) |
| 1921 | + (*current_liboctave_error_handler) |
| 1922 | + ("eigs: array too large for Fortran integers"); |
| 1923 | + if (octave::math::int_multiply_overflow (3 * p, p + 2, &lwork)) |
| 1924 | + (*current_liboctave_error_handler) |
| 1925 | + ("eigs: array too large for Fortran integers"); |
| 1926 | + |
| 1927 | + OCTAVE_LOCAL_BUFFER (double, v, elems); |
1895 | 1928 | OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1); |
1896 | 1929 | OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1); |
1897 | 1930 | double *presid = resid.rwdata (); |
@@ -2224,9 +2257,17 @@ EigsRealNonSymmetricMatrixShift (const M& m, double sigmar, |
2224 | 2257 | if (! LuAminusSigmaB (m, b, cholB, permB, sigmar, L, U, P, Q, r)) |
2225 | 2258 | return -1; |
2226 | 2259 |
|
2227 | | - F77_INT lwork = 3 * p * (p + 2); |
| 2260 | + F77_INT elems; |
| 2261 | + F77_INT lwork; |
| 2262 | + |
| 2263 | + if (octave::math::int_multiply_overflow (n, p + 1, &elems)) |
| 2264 | + (*current_liboctave_error_handler) |
| 2265 | + ("eigs: array too large for Fortran integers"); |
| 2266 | + if (octave::math::int_multiply_overflow (3 * p, p + 2, &lwork)) |
| 2267 | + (*current_liboctave_error_handler) |
| 2268 | + ("eigs: array too large for Fortran integers"); |
2228 | 2269 |
|
2229 | | - OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1)); |
| 2270 | + OCTAVE_LOCAL_BUFFER (double, v, elems); |
2230 | 2271 | OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1); |
2231 | 2272 | OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1); |
2232 | 2273 | double *presid = resid.rwdata (); |
@@ -2635,11 +2676,20 @@ EigsRealNonSymmetricFunc (EigsFunc fcn, octave_idx_type n_arg, |
2635 | 2676 |
|
2636 | 2677 | F77_INT ido = 0; |
2637 | 2678 | int iter = 0; |
2638 | | - F77_INT lwork = 3 * p * (p + 2); |
| 2679 | + F77_INT elems; |
| 2680 | + F77_INT lwork; |
| 2681 | + |
| 2682 | + if (octave::math::int_multiply_overflow (n, p + 1, &elems)) |
| 2683 | + (*current_liboctave_error_handler) |
| 2684 | + ("eigs: array too large for Fortran integers"); |
| 2685 | + if (octave::math::int_multiply_overflow (3 * p, p + 2, &lwork)) |
| 2686 | + (*current_liboctave_error_handler) |
| 2687 | + ("eigs: array too large for Fortran integers"); |
2639 | 2688 |
|
2640 | | - OCTAVE_LOCAL_BUFFER (double, v, n * (p + 1)); |
| 2689 | + OCTAVE_LOCAL_BUFFER (double, v, elems); |
2641 | 2690 | OCTAVE_LOCAL_BUFFER (double, workl, lwork + 1); |
2642 | 2691 | OCTAVE_LOCAL_BUFFER (double, workd, 3 * n + 1); |
| 2692 | + |
2643 | 2693 | double *presid = resid.rwdata (); |
2644 | 2694 |
|
2645 | 2695 | do |
@@ -3055,9 +3105,17 @@ EigsComplexNonSymmetricMatrix (const M& m, const std::string typ, |
3055 | 3105 |
|
3056 | 3106 | F77_INT ido = 0; |
3057 | 3107 | int iter = 0; |
3058 | | - F77_INT lwork = p * (3 * p + 5); |
| 3108 | + F77_INT elems; |
| 3109 | + F77_INT lwork; |
| 3110 | + |
| 3111 | + if (octave::math::int_multiply_overflow (n, p, &elems)) |
| 3112 | + (*current_liboctave_error_handler) |
| 3113 | + ("eigs: array too large for Fortran integers"); |
| 3114 | + if (octave::math::int_multiply_overflow (p, 3 * p + 5, &lwork)) |
| 3115 | + (*current_liboctave_error_handler) |
| 3116 | + ("eigs: array too large for Fortran integers"); |
3059 | 3117 |
|
3060 | | - OCTAVE_LOCAL_BUFFER (Complex, v, n * p); |
| 3118 | + OCTAVE_LOCAL_BUFFER (Complex, v, elems); |
3061 | 3119 | OCTAVE_LOCAL_BUFFER (Complex, workl, lwork); |
3062 | 3120 | OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n); |
3063 | 3121 | OCTAVE_LOCAL_BUFFER (double, rwork, p); |
@@ -3342,9 +3400,17 @@ EigsComplexNonSymmetricMatrixShift (const M& m, Complex sigma, |
3342 | 3400 | if (! LuAminusSigmaB (m, b, cholB, permB, sigma, L, U, P, Q, r)) |
3343 | 3401 | return -1; |
3344 | 3402 |
|
3345 | | - F77_INT lwork = p * (3 * p + 5); |
| 3403 | + F77_INT elems; |
| 3404 | + F77_INT lwork; |
| 3405 | + |
| 3406 | + if (octave::math::int_multiply_overflow (n, p, &elems)) |
| 3407 | + (*current_liboctave_error_handler) |
| 3408 | + ("eigs: array too large for Fortran integers"); |
| 3409 | + if (octave::math::int_multiply_overflow (p, 3 * p + 5, &lwork)) |
| 3410 | + (*current_liboctave_error_handler) |
| 3411 | + ("eigs: array too large for Fortran integers"); |
3346 | 3412 |
|
3347 | | - OCTAVE_LOCAL_BUFFER (Complex, v, n * p); |
| 3413 | + OCTAVE_LOCAL_BUFFER (Complex, v, elems); |
3348 | 3414 | OCTAVE_LOCAL_BUFFER (Complex, workl, lwork); |
3349 | 3415 | OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n); |
3350 | 3416 | OCTAVE_LOCAL_BUFFER (double, rwork, p); |
@@ -3703,9 +3769,17 @@ EigsComplexNonSymmetricFunc (EigsComplexFunc fcn, octave_idx_type n_arg, |
3703 | 3769 |
|
3704 | 3770 | F77_INT ido = 0; |
3705 | 3771 | int iter = 0; |
3706 | | - F77_INT lwork = p * (3 * p + 5); |
| 3772 | + F77_INT elems; |
| 3773 | + F77_INT lwork; |
| 3774 | + |
| 3775 | + if (octave::math::int_multiply_overflow (n, p, &elems)) |
| 3776 | + (*current_liboctave_error_handler) |
| 3777 | + ("eigs: array too large for Fortran integers"); |
| 3778 | + if (octave::math::int_multiply_overflow (p, 3 * p + 5, &lwork)) |
| 3779 | + (*current_liboctave_error_handler) |
| 3780 | + ("eigs: array too large for Fortran integers"); |
3707 | 3781 |
|
3708 | | - OCTAVE_LOCAL_BUFFER (Complex, v, n * p); |
| 3782 | + OCTAVE_LOCAL_BUFFER (Complex, v, elems); |
3709 | 3783 | OCTAVE_LOCAL_BUFFER (Complex, workl, lwork); |
3710 | 3784 | OCTAVE_LOCAL_BUFFER (Complex, workd, 3 * n); |
3711 | 3785 | OCTAVE_LOCAL_BUFFER (double, rwork, p); |
|
0 commit comments