Skip to content

Commit 3ac712d

Browse files
committed
CAY-2898 Crypto: NPE in a ColumnQuery
1 parent 8f17977 commit 3ac712d

4 files changed

Lines changed: 87 additions & 1 deletion

File tree

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ CAY-2879 Negative number for non parameterized ObjectSelect query not processed
2929
CAY-2883 License and notice templates are not processed by the Gradle build
3030
CAY-2885 Modeler: DbImport fails to load DB schema view
3131
CAY-2896 Inserting two identical objects into two datamaps stores both objects in the last used datamap
32+
CAY-2898 Crypto: NPE in a ColumnQuery
3233

3334
----------------------------------
3435
Release: 5.0-M1

cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ private class DecoratedScalarRowReader implements RowReader<Object> {
159159
@Override
160160
public Object readRow(ResultSet resultSet) {
161161
Object value = delegateReader.readRow(resultSet);
162-
if(valueDecryptor == null) {
162+
if(valueDecryptor == null || value == null) {
163163
return value;
164164
}
165165
return valueDecryptor.decrypt(bytesDecryptor, value);

cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_AES128_GZIP_IT.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,72 @@ public void test_SelectQueryWithOptimisticLocking() throws SQLException {
190190
assertEquals(str+"A", result.get(0).getCryptoString());
191191
}
192192

193+
@Test
194+
public void test_ScalarColumnQuery() throws SQLException {
195+
// make sure compression is on...
196+
byte[] cryptoBytes1 = CryptoUnitUtils.bytesOfSize(GZIP_THRESHOLD + 101);
197+
byte[] cryptoBytes2 = CryptoUnitUtils.bytesOfSize(GZIP_THRESHOLD + 102);
198+
199+
ObjectContext context = runtime.newContext();
200+
201+
Table2 t1 = context.newObject(Table2.class);
202+
t1.setPlainBytes("a".getBytes());
203+
t1.setCryptoBytes(cryptoBytes1);
204+
205+
Table2 t2 = context.newObject(Table2.class);
206+
t2.setPlainBytes("b".getBytes());
207+
t2.setCryptoBytes(cryptoBytes2);
208+
209+
Table2 t3 = context.newObject(Table2.class);
210+
t3.setPlainBytes("c".getBytes());
211+
t3.setCryptoBytes(null);
212+
213+
context.commitChanges();
214+
215+
List<byte[]> result = ObjectSelect.query(Table2.class)
216+
.column(Table2.CRYPTO_BYTES)
217+
.orderBy(Table2.PLAIN_BYTES.asc())
218+
.select(runtime.newContext());
219+
220+
assertEquals(3, result.size());
221+
assertArrayEquals(cryptoBytes1, result.get(0));
222+
assertArrayEquals(cryptoBytes2, result.get(1));
223+
assertArrayEquals(null, result.get(2));
224+
}
225+
226+
@Test
227+
public void test_MultipleColumnsQuery() throws SQLException {
228+
// make sure compression is on...
229+
byte[] cryptoBytes1 = CryptoUnitUtils.bytesOfSize(GZIP_THRESHOLD + 101);
230+
byte[] cryptoBytes2 = CryptoUnitUtils.bytesOfSize(GZIP_THRESHOLD + 102);
231+
232+
ObjectContext context = runtime.newContext();
233+
234+
Table2 t1 = context.newObject(Table2.class);
235+
t1.setPlainBytes("a".getBytes());
236+
t1.setCryptoBytes(cryptoBytes1);
237+
238+
Table2 t2 = context.newObject(Table2.class);
239+
t2.setPlainBytes("b".getBytes());
240+
t2.setCryptoBytes(cryptoBytes2);
241+
242+
Table2 t3 = context.newObject(Table2.class);
243+
t3.setPlainBytes("c".getBytes());
244+
t3.setCryptoBytes(null);
245+
246+
context.commitChanges();
247+
248+
List<Object[]> result = ObjectSelect.query(Table2.class)
249+
.columns(Table2.CRYPTO_BYTES, Table2.PLAIN_BYTES)
250+
.orderBy(Table2.PLAIN_BYTES.asc())
251+
.select(runtime.newContext());
252+
253+
assertEquals(3, result.size());
254+
assertArrayEquals(cryptoBytes1, (byte[])result.get(0)[0]);
255+
assertArrayEquals("a".getBytes(), (byte[])result.get(0)[1]);
256+
assertArrayEquals(cryptoBytes2, (byte[])result.get(1)[0]);
257+
assertArrayEquals("b".getBytes(), (byte[])result.get(1)[1]);
258+
assertArrayEquals(null, (byte[])result.get(2)[0]);
259+
}
260+
193261
}

cayenne-crypto/src/test/java/org/apache/cayenne/crypto/Runtime_AES128_IT.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,23 @@ public void test_ColumnQuerySingleScalar() {
333333
assertEquals("test", result.get(0));
334334
}
335335

336+
@Test
337+
public void test_ColumnQuerySingleScalarNull() {
338+
ObjectContext context = runtime.newContext();
339+
340+
Table1 t1 = context.newObject(Table1.class);
341+
t1.setCryptoInt(1);
342+
t1.setCryptoString(null);
343+
context.commitChanges();
344+
345+
List<String> result = ObjectSelect
346+
.columnQuery(Table1.class, Table1.CRYPTO_STRING)
347+
.select(context);
348+
349+
assertEquals(1, result.size());
350+
assertNull(result.get(0));
351+
}
352+
336353
@Test
337354
public void test_ColumnQueryMultipleScalars() {
338355
ObjectContext context = runtime.newContext();

0 commit comments

Comments
 (0)