|
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