From be2daf0c8b1b8679d956273ecd1987307868760b Mon Sep 17 00:00:00 2001 From: Thomas Carmet <8408330+tcarmet@users.noreply.github.com> Date: Wed, 27 May 2026 17:32:44 -0700 Subject: [PATCH] CLDSRV-909: Reject CopyObject when source exceeds 5 GiB --- lib/api/objectCopy.js | 10 ++++++++ tests/unit/api/objectCopy.js | 47 +++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/lib/api/objectCopy.js b/lib/api/objectCopy.js index 02b0a31d5b..b504e1d9f6 100644 --- a/lib/api/objectCopy.js +++ b/lib/api/objectCopy.js @@ -351,6 +351,16 @@ function objectCopy(authInfo, request, sourceBucket, request.sourceServerAccessLog && (request.sourceServerAccessLog.error = err); return next(err, destBucketMD); } + const sourceSize = parseInt(sourceObjMD['content-length'], 10); + if (sourceSize > constants.maximumAllowedUploadSize) { + log.debug('copy source object too large', { sourceSize }); + const err = errorInstances.InvalidRequest.customizeDescription( + 'The specified copy source is larger than the maximum ' + + `allowable size for a copy source: ${constants.maximumAllowedUploadSize}`); + // eslint-disable-next-line no-param-reassign + request.sourceServerAccessLog && (request.sourceServerAccessLog.error = err); + return next(err, destBucketMD); + } const headerValResult = validateHeaders(request.headers, sourceObjMD['last-modified'], diff --git a/tests/unit/api/objectCopy.js b/tests/unit/api/objectCopy.js index 2448f3276f..533cbb038f 100644 --- a/tests/unit/api/objectCopy.js +++ b/tests/unit/api/objectCopy.js @@ -14,7 +14,8 @@ const { cleanup, DummyRequestLogger, makeAuthInfo, versioningTestUtils } const mpuUtils = require('../utils/mpuUtils'); const metadata = require('../metadataswitch'); const { data } = require('../../../lib/data/wrapper'); -const { objectLocationConstraintHeader } = require('../../../constants'); +const constants = require('../../../constants'); +const { objectLocationConstraintHeader } = constants; const { fakeMetadataArchive } = require('../../functional/aws-node-sdk/test/utils/init'); const { config } = require('../../../lib/Config'); @@ -640,3 +641,47 @@ describe('objectCopy with objectKeyByteLimit', () => { }); }); }); + +describe('objectCopy source size limit', () => { + const testPutObjectRequest = versioningTestUtils.createPutObjectRequest(sourceBucketName, objectKey, objData[0]); + const sourceSize = objData[0].length; + let originalMaximumUploadSize; + + before(done => { + cleanup(); + originalMaximumUploadSize = constants.maximumAllowedUploadSize; + async.series([ + callback => bucketPut(authInfo, putDestBucketRequest, log, callback), + callback => bucketPut(authInfo, putSourceBucketRequest, log, callback), + callback => objectPut(authInfo, testPutObjectRequest, undefined, log, callback), + ], done); + }); + + after(() => { + constants.maximumAllowedUploadSize = originalMaximumUploadSize; + cleanup(); + }); + + it('should allow CopyObject when source size equals the limit', done => { + constants.maximumAllowedUploadSize = sourceSize; + const testObjectCopyRequest = _createObjectCopyRequest(destBucketName); + objectCopy(authInfo, testObjectCopyRequest, sourceBucketName, objectKey, + undefined, log, err => { + assert.ifError(err); + done(); + }); + }); + + it('should reject CopyObject when source size exceeds the limit', done => { + constants.maximumAllowedUploadSize = sourceSize - 1; + const testObjectCopyRequest = _createObjectCopyRequest(destBucketName); + objectCopy(authInfo, testObjectCopyRequest, sourceBucketName, objectKey, + undefined, log, err => { + assert(err); + assert.strictEqual(err.is.InvalidRequest, true); + assert.match(err.description, + /The specified copy source is larger than the maximum allowable size for a copy source/); + done(); + }); + }); +});