Use uint64 for backups.proto object length
This commit is contained in:
parent
024fa9ce5f
commit
06519ce9d1
@ -86,7 +86,7 @@ public class Cdn3RemoteStorageManager implements RemoteStorageManager {
|
||||
public CompletionStage<Void> copy(
|
||||
final int sourceCdn,
|
||||
final String sourceKey,
|
||||
final int expectedSourceLength,
|
||||
final long expectedSourceLength,
|
||||
final MediaEncryptionParameters encryptionParameters,
|
||||
final String destinationKey) {
|
||||
final String sourceScheme = this.sourceSchemes.get(sourceCdn);
|
||||
@ -132,10 +132,10 @@ public class Cdn3RemoteStorageManager implements RemoteStorageManager {
|
||||
*/
|
||||
record Cdn3CopyRequest(
|
||||
String encryptionKey, String hmacKey,
|
||||
SourceDescriptor source, int expectedSourceLength,
|
||||
SourceDescriptor source, long expectedSourceLength,
|
||||
String dst) {
|
||||
|
||||
Cdn3CopyRequest(MediaEncryptionParameters parameters, SourceDescriptor source, int expectedSourceLength,
|
||||
Cdn3CopyRequest(MediaEncryptionParameters parameters, SourceDescriptor source, long expectedSourceLength,
|
||||
String dst) {
|
||||
this(Base64.getEncoder().encodeToString(parameters.aesEncryptionKey().getEncoded()),
|
||||
Base64.getEncoder().encodeToString(parameters.hmacSHA256Key().getEncoded()),
|
||||
|
||||
@ -18,7 +18,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
public record CopyParameters(
|
||||
int sourceCdn,
|
||||
String sourceKey,
|
||||
int sourceLength,
|
||||
long sourceLength,
|
||||
MediaEncryptionParameters encryptionParameters,
|
||||
byte[] destinationMediaId) {
|
||||
|
||||
@ -35,16 +35,17 @@ public record CopyParameters(
|
||||
///
|
||||
/// @return the size, in bytes, of the ciphertext of a media object with the given `inputSize`
|
||||
@VisibleForTesting
|
||||
static long destinationObjectSize(final int inputSize) {
|
||||
static long destinationObjectSize(final long inputSize) {
|
||||
if (inputSize < 0) {
|
||||
throw new IllegalArgumentException("Size must be non-negative, but was " + inputSize);
|
||||
}
|
||||
|
||||
// AES-256 has 16-byte block size, and always adds a block if the plaintext is a multiple of the block size
|
||||
final long numBlocks = ((long) inputSize + 16) / 16;
|
||||
final long numBlocks = Math.addExact(inputSize, 16L) / 16;
|
||||
final long cipherTextLength = Math.multiplyExact(numBlocks, 16);
|
||||
|
||||
// 16-byte IV will be generated and prepended to the ciphertext
|
||||
// 16-byte IV will be generated and prepended to the ciphertext.
|
||||
// IV + AES-256 encrypted data + HmacSHA256
|
||||
return 16 + (numBlocks * 16) + 32;
|
||||
return Math.addExact(cipherTextLength, 16L + 32);
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ public interface RemoteStorageManager {
|
||||
CompletionStage<Void> copy(
|
||||
int sourceCdn,
|
||||
String sourceKey,
|
||||
int expectedSourceLength,
|
||||
long expectedSourceLength,
|
||||
MediaEncryptionParameters encryptionParameters,
|
||||
String dstKey);
|
||||
|
||||
|
||||
@ -224,8 +224,7 @@ public class BackupsAnonymousGrpcService extends SimpleBackupsAnonymousGrpc.Back
|
||||
copyQuota = backupManager.getCopyQuota(backupUser,
|
||||
request.getItemsList().stream().map(item -> new CopyParameters(
|
||||
item.getSourceAttachmentCdn(), item.getSourceKey(),
|
||||
// uint32 in proto, make sure it fits in a signed int
|
||||
fromUnsignedExact(item.getObjectLength()),
|
||||
item.getObjectLength(),
|
||||
new MediaEncryptionParameters(item.getEncryptionKey().toByteArray(), item.getHmacKey().toByteArray()),
|
||||
item.getMediaId().toByteArray())).toList(), maxAttachmentSize);
|
||||
} catch (BackupFailedZkAuthenticationException e) {
|
||||
@ -351,17 +350,6 @@ public class BackupsAnonymousGrpcService extends SimpleBackupsAnonymousGrpc.Back
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an int from a proto uint32 to a signed positive integer, throwing if the value exceeds
|
||||
* {@link Integer#MAX_VALUE}. To convert to a long, see {@link Integer#toUnsignedLong(int)}
|
||||
*/
|
||||
private static int fromUnsignedExact(final int i) {
|
||||
if (i < 0) {
|
||||
throw GrpcExceptions.invalidArguments("integer length too large");
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private interface Deserializer<T> {
|
||||
|
||||
T deserialize(byte[] bytes) throws InvalidInputException, InvalidKeyException;
|
||||
|
||||
@ -410,7 +410,7 @@ message CopyMediaItem {
|
||||
|
||||
// The length of the source attachment before the encryption applied by the
|
||||
// copy operation
|
||||
uint32 object_length = 3;
|
||||
uint64 object_length = 3;
|
||||
|
||||
// media_id to copy on to the backup CDN
|
||||
bytes media_id = 4 [(require.exactlySize) = 15];
|
||||
|
||||
@ -525,11 +525,11 @@ public class BackupManagerTest {
|
||||
|
||||
when(tusCredentialGenerator.generateUpload(any(), anyLong()))
|
||||
.thenReturn(new BackupUploadDescriptor(3, "", Collections.emptyMap(), ""));
|
||||
when(remoteStorageManager.copy(eq(3), eq("success"), eq(100), any(), any()))
|
||||
when(remoteStorageManager.copy(eq(3), eq("success"), eq(100L), any(), any()))
|
||||
.thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(remoteStorageManager.copy(eq(3), eq("missing"), eq(200), any(), any()))
|
||||
when(remoteStorageManager.copy(eq(3), eq("missing"), eq(200L), any(), any()))
|
||||
.thenReturn(CompletableFuture.failedFuture(new SourceObjectNotFoundException()));
|
||||
when(remoteStorageManager.copy(eq(3), eq("badlength"), eq(300), any(), any()))
|
||||
when(remoteStorageManager.copy(eq(3), eq("badlength"), eq(300L), any(), any()))
|
||||
.thenReturn(CompletableFuture.failedFuture(new InvalidLengthException("")));
|
||||
|
||||
final List<CopyResult> results = backupManager
|
||||
|
||||
Loading…
Reference in New Issue
Block a user