From 921108ea29fcc55ceaa60f98179cfec9f30f57e5 Mon Sep 17 00:00:00 2001 From: ddeclerck Date: Fri, 20 Dec 2024 15:44:14 +0000 Subject: [PATCH] follow-up commit to r5403 - fix an out of bounds read access in optimized_move_display_to_edited --- libcob/move.c | 45 ++++++++++++++++++++------------- tests/testsuite.src/run_misc.at | 24 ++++++++++++++++++ 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/libcob/move.c b/libcob/move.c index 1bd73b44..25dccfc2 100644 --- a/libcob/move.c +++ b/libcob/move.c @@ -1114,7 +1114,7 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) continue; } for (n = p->times_repeated; n > 0; n--) { - unsigned int src_num = COB_D2I (*src); + unsigned int src_num; #ifndef NDEBUG if (dst >= dst_end) { cob_runtime_error ("optimized_move_display_to_edited: overflow in destination field"); @@ -1125,6 +1125,7 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) case '9': suppress_zero = 0; + src_num = COB_D2I (*src); *dst = COB_I2D (src_num); if (src_num != 0) { is_zero = 0; @@ -1134,6 +1135,7 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) break; case 'Z': + src_num = COB_D2I (*src); *dst = COB_I2D (src_num); pad = ' '; if (src_num != 0) { @@ -1148,6 +1150,7 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) break; case '*': + src_num = COB_D2I (*src); *dst = COB_I2D (src_num); have_check_protect = 1; if (src_num != 0) { @@ -1174,23 +1177,26 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) sign_position = dst; dst++; break; - } else if (src_num == 0 && suppress_zero && !have_decimal_point) { - *prev_float_char = ' '; - prev_float_char = dst; - sign_position = dst; - *dst = c; - dst++; - src++; - break; } else { - *dst = COB_I2D (src_num); - if (src_num != 0) { - is_zero = 0; - suppress_zero = 0; + src_num = COB_D2I (*src); + if (src_num == 0 && suppress_zero && !have_decimal_point) { + *prev_float_char = ' '; + prev_float_char = dst; + sign_position = dst; + *dst = c; + dst++; + src++; + break; + } else { + *dst = COB_I2D (src_num); + if (src_num != 0) { + is_zero = 0; + suppress_zero = 0; + } + dst++; + src++; + break; } - dst++; - src++; - break; } case '.': @@ -1288,14 +1294,16 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) prev_float_char = dst; dst++; break; - } else if ((src_num == 0) && (suppress_zero) && (!have_decimal_point)) { + } else { + src_num = COB_D2I (*src); + if ((src_num == 0) && (suppress_zero) && (!have_decimal_point)) { *prev_float_char = ' '; prev_float_char = dst; *dst = c; dst++; src++; break; - } else { + } else { *dst = COB_I2D (src_num); if (src_num != 0) { is_zero = 0; @@ -1304,6 +1312,7 @@ optimized_move_display_to_edited (cob_field *f1, cob_field *f2) dst++; src++; break; + } } } } diff --git a/tests/testsuite.src/run_misc.at b/tests/testsuite.src/run_misc.at index 97c3c90e..97157f4f 100644 --- a/tests/testsuite.src/run_misc.at +++ b/tests/testsuite.src/run_misc.at @@ -15202,3 +15202,27 @@ AT_CHECK([COB_PROF_ENABLE=1 COB_PROF_FILE=prof.csv $COBCRUN_DIRECT ./caller], [0 ]) AT_CLEANUP + + +AT_SETUP([MOVE to NUMERIC-EDITED safety]) + +AT_DATA([prog.cob], [ + IDENTIFICATION DIVISION. + PROGRAM-ID. prog. + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 X PIC 9(5) VALUE 12345. + 01 Y PIC 9(5)CR. + PROCEDURE DIVISION. + MOVE X TO Y. + IF Y(1:) NOT = "12345" THEN + DISPLAY "EXPECTED '12345'" + DISPLAY "GOT '" Y(1:) "'" + END-IF. + STOP RUN. +]) + +AT_CHECK([$COMPILE prog.cob]) +AT_CHECK([$COBCRUN_DIRECT ./prog], [0], [], []) + +AT_CLEANUP