This is an automated email from the ASF dual-hosted git repository.
zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git
The following commit(s) were added to refs/heads/main by this push:
new 62ce681f test(parquet): cover plaintext-footer CTR interoperability
(#1438)
62ce681f is described below
commit 62ce681feb19706e0e9a70d3a393de0f4822d815
Author: autoCAT <[email protected]>
AuthorDate: Mon Nov 2 12:22:00 2026 -0800
test(parquet): cover plaintext-footer CTR interoperability (#1438)
### Rationale for this change
The encryption configuration suite omits two encrypted columns with
AES_GCM_CTR_V1 and a plaintext footer. The shared C++ fixture added in
apache/parquet-testing#130 covers this combination and was generated
using a branch containing apache/arrow#54884.
This follows the writer correction in #1412 with a reusable
interoperability regression. Adam Reeve authored the shared fixture.
### What changes are included in this PR?
* Add the missing writer configuration for DataPageV1/V2 and
Snappy/uncompressed output.
* Read generated Go files and the shared C++ fixture through the
existing key-retrieval, explicit-key, AAD-mismatch and plaintext-only
checks, including values and page indexes.
* Fast-forward the parquet-testing submodule from 92d45b0 to eedfad3,
which includes the fixture and intervening dataset updates. No
production code changes.
### Are these changes tested?
* The focused suite passes with `-race -tags assert` and with `-tags
assert,noasm`.
* Temporarily restoring the old #1412 metadata logic makes all four new
generated-file variants fail. The shared C++ fixture's four decryption
configurations still pass in that control. The production source was
restored afterward.
* All 13 test-bearing Parquet packages pass with the race detector; five
additional packages have no test files.
* Vet and repository-pinned lint pass for `./parquet`; gofmt, diff
checks and Apache RAT pass.
### Are there any user-facing changes?
No API or runtime behavior changes.
AI was used for the tests and PR description.
---
parquet-testing | 2 +-
parquet/encryption_read_config_test.go | 12 +++++++++---
parquet/encryption_write_config_test.go | 17 +++++++++++++++++
3 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/parquet-testing b/parquet-testing
index 92d45b07..eedfad3f 160000
--- a/parquet-testing
+++ b/parquet-testing
@@ -1 +1 @@
-Subproject commit 92d45b0752487a4b55fb7f1581c8126ee3e73b0d
+Subproject commit eedfad3f086678d282a00d8ff3cf8932d5d29af5
diff --git a/parquet/encryption_read_config_test.go
b/parquet/encryption_read_config_test.go
index 06508b7d..9b1fcffa 100644
--- a/parquet/encryption_read_config_test.go
+++ b/parquet/encryption_read_config_test.go
@@ -70,7 +70,7 @@ import (
* (instead of key retrieval callback).
* - Decryption Configuration 4: PlainText Footer mode - test legacy reads,
* read the footer + all non-encrypted
columns.
- * (pairs with encryption configuration 3)
+ * (pairs with encryption configurations 3
and 7)
*
* The encrypted parquet files that is read was encrypted using one of the
configurations
* below:
@@ -91,6 +91,8 @@ import (
* identity storage in file metadata.
* - Encryption configuration 6: Encrypt two columns and the footer, with
different
* keys. Use the alternative (AES_GCM_CTR_V1)
algorithm.
+ * - Encryption configuration 7: Encrypt two columns with a plaintext
footer, using
+ * the alternative (AES_GCM_CTR_V1) algorithm.
*/
func getDataDir() string {
@@ -546,8 +548,8 @@ func (d *TestDecryptionSuite) checkResults(fileName string,
decryptionConfig, en
}
}
- // decryption config 4 can only work when the encryption config is 3
- if decryptionConfig == 4 && encryptionConfig != 3 {
+ // Decryption config 4 reads plaintext footers and unencrypted columns.
+ if decryptionConfig == 4 && encryptionConfig != 3 && encryptionConfig
!= 7 {
return
}
d.NotPanics(decFn)
@@ -587,6 +589,10 @@ func (d *TestDecryptionSuite) TestDecryption() {
{"encrypt_columns_and_footer_ctr.parquet.uncompressed.encrypted", 6, false},
{"encrypt_columns_and_footer_ctr.parquet.v2.encrypted", 6,
false},
{"encrypt_columns_and_footer_ctr.parquet.v2.uncompressed.encrypted", 6, false},
+ {"encrypt_columns_plaintext_footer_ctr.parquet.encrypted", 7,
true},
+
{"encrypt_columns_plaintext_footer_ctr.parquet.uncompressed.encrypted", 7,
false},
+ {"encrypt_columns_plaintext_footer_ctr.parquet.v2.encrypted",
7, false},
+
{"encrypt_columns_plaintext_footer_ctr.parquet.v2.uncompressed.encrypted", 7,
false},
}
for _, tt := range tests {
d.Run(tt.file, func() {
diff --git a/parquet/encryption_write_config_test.go
b/parquet/encryption_write_config_test.go
index 9063ca7a..f069cc19 100644
--- a/parquet/encryption_write_config_test.go
+++ b/parquet/encryption_write_config_test.go
@@ -59,6 +59,8 @@ import (
* identity storage in file metadata.
* - Encryption configuration 6: Encrypt two columns and the footer, with
different
* keys. Use the alternative (AES_GCM_CTR_V1)
algorithm.
+ * - Encryption configuration 7: Encrypt two columns with a plaintext
footer, using
+ * the alternative (AES_GCM_CTR_V1) algorithm.
*/
var tempdir string
@@ -345,6 +347,21 @@ func (en *EncryptionConfigTestSuite)
TestEncryptTwoColumnsAndFooterAesGcmCtr() {
parquet.WithDataPageVersion(parquet.DataPageV2))
}
+// Encryption Config 7: Encrypt two columns with a plaintext footer.
+// Use AES_GCM_CTR_V1
+func (en *EncryptionConfigTestSuite)
TestEncryptTwoColumnsPlaintextFooterAesGcmCtr() {
+ encryptCols := make(parquet.ColumnPathToEncryptionPropsMap)
+ encryptCols[en.pathToDoubleField] =
parquet.NewColumnEncryptionProperties(en.pathToDoubleField,
parquet.WithKey(en.columnEncryptionKey1), parquet.WithKeyID("kc1"))
+ encryptCols[en.pathToFloatField] =
parquet.NewColumnEncryptionProperties(en.pathToFloatField,
parquet.WithKey(en.columnEncryptionKey2), parquet.WithKeyID("kc2"))
+
+ props := parquet.NewFileEncryptionProperties(en.footerEncryptionKey,
parquet.WithFooterKeyMetadata("kf"), parquet.WithEncryptedColumns(encryptCols),
parquet.WithAlg(parquet.AesCtr), parquet.WithPlaintextFooter())
+ en.encryptFile(props.Clone(""),
"tmp_encrypt_columns_plaintext_footer_ctr.parquet.encrypted")
+ en.encryptFile(props.Clone(""),
"tmp_encrypt_columns_plaintext_footer_ctr.parquet.uncompressed.encrypted",
parquet.WithCompression(compress.Codecs.Uncompressed))
+ en.encryptFile(props.Clone(""),
"tmp_encrypt_columns_plaintext_footer_ctr.parquet.v2.encrypted",
parquet.WithDataPageVersion(parquet.DataPageV2))
+ en.encryptFile(props.Clone(""),
"tmp_encrypt_columns_plaintext_footer_ctr.parquet.v2.uncompressed.encrypted",
parquet.WithCompression(compress.Codecs.Uncompressed),
+ parquet.WithDataPageVersion(parquet.DataPageV2))
+}
+
func TestFileEncryption(t *testing.T) {
suite.Run(t, new(EncryptionConfigTestSuite))
}