diff options
Diffstat (limited to 'internal/contentenc')
| -rw-r--r-- | internal/contentenc/offsets.go | 15 | 
1 files changed, 14 insertions, 1 deletions
| diff --git a/internal/contentenc/offsets.go b/internal/contentenc/offsets.go index fdeb583..7487baf 100644 --- a/internal/contentenc/offsets.go +++ b/internal/contentenc/offsets.go @@ -31,7 +31,11 @@ func (be *ContentEnc) BlockNoToPlainOff(blockNo uint64) uint64 {  	return blockNo * be.plainBS  } -// CipherSizeToPlainSize calculates the plaintext size from a ciphertext size +// CipherSizeToPlainSize calculates the plaintext size `plainSize` from a +// ciphertext size `cipherSize` (in bytes). +// +// Not all ciphertext sizes are legal due to the per-block overheads. +// For an illegal cipherSize, we return a best guess plainSize.  func (be *ContentEnc) CipherSizeToPlainSize(cipherSize uint64) uint64 {  	// Zero-sized files stay zero-sized  	if cipherSize == 0 { @@ -49,6 +53,15 @@ func (be *ContentEnc) CipherSizeToPlainSize(cipherSize uint64) uint64 {  		return 0  	} +	// If the last block is incomplete, pad it to 1 byte of plaintext +	// (= 33 bytes of ciphertext). +	lastBlockSize := (cipherSize - HeaderLen) % be.cipherBS +	if lastBlockSize > 0 && lastBlockSize <= be.BlockOverhead() { +		tmp := cipherSize - lastBlockSize + be.BlockOverhead() + 1 +		tlog.Warn.Printf("cipherSize %d: incomplete last block (%d bytes), padding to %d bytes", cipherSize, lastBlockSize, tmp) +		cipherSize = tmp +	} +  	// Block number at last byte  	blockNo := be.CipherOffToBlockNo(cipherSize - 1)  	blockCount := blockNo + 1 | 
