From f76ab0b83b5a9936789674502918c7ead8eafd8b Mon Sep 17 00:00:00 2001 From: Michael Mikonos <127171689+mknos@users.noreply.github.com> Date: Sat, 10 Feb 2024 12:03:20 +0800 Subject: [PATCH] cmp: check length off-by-one * $checklength is the maximum offset in buffer to check which byte(s) in the 2 buffers are not equal * The subsequent loop is from 0 to $checklength, so avoid potentially accessing $bytes1[$chunk_size] * If $read_in1 and $read_in2 are equal to $chunk_size, the value of $checklength is not decremented * Calculate minimum of $read_in1 and $read_in2 (these will never exceed $chunk_size), then decrement by 1 --- bin/cmp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/bin/cmp b/bin/cmp index 10f2eba5..9b68c3d4 100755 --- a/bin/cmp +++ b/bin/cmp @@ -38,6 +38,7 @@ use strict; use File::Basename qw(basename); use Getopt::Std qw(getopts); +use List::Util qw(min); use constant EX_SUCCESS => 0; use constant EX_DIFFERENT => 1; @@ -174,12 +175,8 @@ if ($skip2) { READ: while (defined ($read_in1 = sysread $fh1, $buffer1, $chunk_size)) { $read_in2 = sysread $fh2, $buffer2, $chunk_size; - my $checklength = $chunk_size; - if ($read_in1 < $chunk_size or $read_in2 < $chunk_size) { - $checklength = ( $read_in1 < $read_in2 ? - $read_in1 : - $read_in2 ) - 1; - } + my $checklength = min($read_in1, $read_in2); + $checklength-- if $checklength; if ($buffer1 ne $buffer2) { my @bytes1 = unpack 'C*', $buffer1;