From e1e524097824366ca21b274e24f57e5872d237ba Mon Sep 17 00:00:00 2001
From: Cristian Maglie <c.maglie@arduino.cc>
Date: Mon, 28 Oct 2024 13:55:36 +0100
Subject: [PATCH 1/3] Do not fail download if archive size do not match
 package_index.json size (checksum is sufficient)

---
 internal/arduino/resources/checksums.go | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/internal/arduino/resources/checksums.go b/internal/arduino/resources/checksums.go
index ecd50b5bcc9..c9309f93e5b 100644
--- a/internal/arduino/resources/checksums.go
+++ b/internal/arduino/resources/checksums.go
@@ -31,6 +31,7 @@ import (
 
 	"github.com/arduino/arduino-cli/internal/i18n"
 	paths "github.com/arduino/go-paths-helper"
+	"github.com/sirupsen/logrus"
 )
 
 // TestLocalArchiveChecksum test if the checksum of the local archive match the checksum of the DownloadResource
@@ -82,20 +83,21 @@ func (r *DownloadResource) TestLocalArchiveChecksum(downloadDir *paths.Path) (bo
 }
 
 // TestLocalArchiveSize test if the local archive size match the DownloadResource size
-func (r *DownloadResource) TestLocalArchiveSize(downloadDir *paths.Path) (bool, error) {
+func (r *DownloadResource) TestLocalArchiveSize(downloadDir *paths.Path) error {
 	filePath, err := r.ArchivePath(downloadDir)
 	if err != nil {
-		return false, errors.New(i18n.Tr("getting archive path: %s", err))
+		return errors.New(i18n.Tr("getting archive path: %s", err))
 	}
 	info, err := filePath.Stat()
 	if err != nil {
-		return false, errors.New(i18n.Tr("getting archive info: %s", err))
+		return errors.New(i18n.Tr("getting archive info: %s", err))
 	}
+	// If the size do not match, just report a warning and continue
+	// (the checksum is sufficient to ensure the integrity of the archive)
 	if info.Size() != r.Size {
-		return false, fmt.Errorf("%s: %d != %d", i18n.Tr("fetched archive size differs from size specified in index"), info.Size(), r.Size)
+		logrus.Warningf("%s: %d != %d", i18n.Tr("fetched archive size differs from size specified in index"), info.Size(), r.Size)
 	}
-
-	return true, nil
+	return nil
 }
 
 // TestLocalArchiveIntegrity checks for integrity of the local archive.
@@ -106,10 +108,8 @@ func (r *DownloadResource) TestLocalArchiveIntegrity(downloadDir *paths.Path) (b
 		return false, nil
 	}
 
-	if ok, err := r.TestLocalArchiveSize(downloadDir); err != nil {
+	if err := r.TestLocalArchiveSize(downloadDir); err != nil {
 		return false, errors.New(i18n.Tr("testing archive size: %s", err))
-	} else if !ok {
-		return false, nil
 	}
 
 	ok, err := r.TestLocalArchiveChecksum(downloadDir)

From 076bc0b1410748ec6b73b9016f4d7d2ec58e5ec7 Mon Sep 17 00:00:00 2001
From: Cristian Maglie <c.maglie@arduino.cc>
Date: Mon, 28 Oct 2024 14:12:38 +0100
Subject: [PATCH 2/3] Added unit tests

---
 internal/arduino/resources/resources_test.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/internal/arduino/resources/resources_test.go b/internal/arduino/resources/resources_test.go
index f5b9b252d1f..0ca1bdd884b 100644
--- a/internal/arduino/resources/resources_test.go
+++ b/internal/arduino/resources/resources_test.go
@@ -82,6 +82,10 @@ func TestDownloadAndChecksums(t *testing.T) {
 	require.NoError(t, err)
 	downloadAndTestChecksum()
 
+	require.NoError(t, r.TestLocalArchiveSize(tmp))
+	r.Size = 500
+	require.NoError(t, r.TestLocalArchiveSize(tmp))
+
 	r.Checksum = ""
 	_, err = r.TestLocalArchiveChecksum(tmp)
 	require.Error(t, err)

From ea7391fbccebd6320d19f3cb3983ee88501b852f Mon Sep 17 00:00:00 2001
From: Cristian Maglie <c.maglie@arduino.cc>
Date: Mon, 28 Oct 2024 15:52:53 +0100
Subject: [PATCH 3/3] Added integration test

---
 internal/integrationtest/core/core_test.go | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/internal/integrationtest/core/core_test.go b/internal/integrationtest/core/core_test.go
index cd28d8286c0..635dce891d6 100644
--- a/internal/integrationtest/core/core_test.go
+++ b/internal/integrationtest/core/core_test.go
@@ -1354,3 +1354,15 @@ func TestReferencedCoreBuildAndRuntimeProperties(t *testing.T) {
 		out.ArrayMustContain(jsonEncode("runtime.platform.path=" + corePlatformPath))
 	}
 }
+
+func TestCoreInstallWithWrongArchiveSize(t *testing.T) {
+	// See: https://github.com/arduino/arduino-cli/issues/2332
+	env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t)
+	defer env.CleanUp()
+
+	_, _, err := cli.Run("--additional-urls", "https://raw.githubusercontent.com/geolink/opentracker-arduino-board/bf6158ebab0402db217bfb02ea61461ddc6f2940/package_opentracker_index.json", "core", "update-index")
+	require.NoError(t, err)
+
+	_, _, err = cli.Run("--additional-urls", "https://raw.githubusercontent.com/geolink/opentracker-arduino-board/bf6158ebab0402db217bfb02ea61461ddc6f2940/package_opentracker_index.json", "core", "install", "opentracker:sam@1.0.5")
+	require.NoError(t, err)
+}