CVE-2023-36480 (published 2023-08-04T15:15Z)

The Aerospike Java client is a Java application that implements a network protocol to communicate with an Aerospike server. Prior to versions 7.0.0, 6.2.0, 5.2.0, and 4.5.0 some of the messages received from the server contain Java objects that the client deserializes when it encounters them without further validation. Attackers that manage to trick clients into communicating with a malicious server can include especially crafted objects in its responses that, once deserialized by the client, force it to execute arbitrary code. This can be abused to take control of the machine the client is running on. Versions 7.0.0, 6.2.0, 5.2.0, and 4.5.0 contain a patch for this issue.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-502
cwe_name: Deserialization of Untrusted Data
description: The product deserializes untrusted data without sufficiently verifying that the resulting data will be valid.
extended_description: 
            It is often convenient to serialize objects for communication or to save them for later use. However, deserialized data or code can often be modified without using the provided accessor functions if it does not use cryptography to protect itself. Furthermore, any cryptography would still be client-side security -- which is a dangerous security assumption.
            Data that is untrusted can not be trusted to be well-formed.
            When developers place no restrictions on "gadget chains," or series of instances and method invocations that can self-execute during the deserialization process (i.e., before the object is returned to the caller), it is sometimes possible for attackers to leverage them to perform unauthorized actions, like generating a shell.
         
         

Fix information:
repo_url: https://github.com/aerospike/aerospike-client-java
commit_details: repo_url: https://github.com/aerospike/aerospike-client-java
author: Brian Nichols
author_date: 2023-07-25 16:52:21-07:00
msg: CVE-2023-36480 CLIENT-2252 Remove all code that used java runtime serialization/deserialization.

Deserialization of java runtime serialized objects has been identified as a security risk by
CodeQL team members @atorralba (Tony Torralba) and @joefarebrother (Joseph Farebrother).

All existing database objects that are serialized using this serialization format will need to
be converted to a safer format (Aerospike native types, protobuf, msgpack, json, xml ...) using
a previous client version.
repository: repo_url: https://github.com/aerospike/aerospike-client-java
repo_name: aerospike/aerospike-client-java
description: Aerospike Java Client Library
repo_language: Java
owner: aerospike
file_changes: filename: Bin.java
change_type: ModificationType.MODIFY
diff: @@ -240,35 +240,6 @@ public final class Bin {
 		this.value = value;
 	}
 
-	/**
-	 * Create bin with an object value. This is the slowest of the Bin constructors because the type
-	 * must be determined using multiple "instanceof" checks. If the object type is unrecognized,
-	 * the default java serializer is used.
-	 * <p>
-	 * To disable this constructor, set {@link com.aerospike.client.Value#DisableSerializer} to true.
-	 *
-	 * @param name		bin name, current limit is 15 characters.
-	 * @param value		bin value
-	 */
-	public Bin(String name, Object value) {
-		this.name = name;
-		this.value = Value.get(value);
-	}
-
-	/**
-	 * Create bin with a blob value.  The value will be java serialized.
-	 * This method is faster than the bin object constructor because the blob is converted
-	 * directly instead of using multiple "instanceof" type checks with a blob default.
-	 * <p>
-	 * To disable this method, set {@link com.aerospike.client.Value#DisableSerializer} to true.
-	 *
-	 * @param name		bin name, current limit is 15 characters.
-	 * @param value		bin value
-	 */
-	public static Bin asBlob(String name, Object value) {
-		return new Bin(name, Value.getAsBlob(value));
-	}
-
 	/**
 	 * Create bin with a null value. This is useful for bin deletions within a record.
 	 *

programming_language: Java
filename: Value.java
change_type: ModificationType.MODIFY
diff: @@ -16,8 +16,6 @@
  */
 package com.aerospike.client;
 
-import java.io.ByteArrayOutputStream;
-import java.io.ObjectOutputStream;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.List;
@@ -52,24 +50,6 @@ public abstract class Value {
 	 */
 	public static boolean UseBoolBin = true;
 
-	/**
-	 * Should default object serializer be disabled. If true, an exception will be thrown when
-	 * a default object serialization is attempted. Default object serialization is triggered
-	 * when a bin constructed by {@link com.aerospike.client.Bin#Bin(String, Object)} or
-	 * {@link com.aerospike.client.Bin#asBlob(String, Object)} is used in a write command
-	 * with an unrecognized object type.
-	 */
-	public static boolean DisableSerializer = false;
-
-	/**
-	 * Should default object deserializer be disabled. If true, an exception will be thrown when
-	 * a default object deserialization is attempted. Default object serialization is triggered
-	 * when serialized data is read/parsed from the server. DisableDeserializer is separate from
-	 * DisableSerializer because there may be cases when no new serialization is allowed, but
-	 * existing serialized objects need to be supported.
-	 */
-	public static boolean DisableDeserializer = false;
-
 	/**
 	 * Should the client return a map when {@link com.aerospike.client.cdt.MapReturnType#KEY_VALUE}
 	 * is specified in a map read operation and the server returns a list of key/value pairs.
@@ -241,13 +221,6 @@ public abstract class Value {
 		return (value == null)? NullValue.INSTANCE : new ValueArray(value);
 	}
 
-	/**
-	 * Get blob or null value instance.
-	 */
-	public static Value getAsBlob(Object value) {
-		return (value == null)? NullValue.INSTANCE : new BlobValue(value);
-	}
-
 	/**
 	 * Get GeoJSON or null value instance.
 	 */
@@ -349,7 +322,7 @@ public abstract class Value {
 			return new BytesValue(bb.array());
 		}
 
-		return new BlobValue(value);
+		throw new AerospikeException("Unsupported type: " + value.getClass().getName());
 	}
 
 	/**
@@ -1260,88 +1233,6 @@ public abstract class Value {
 		}
 	}
 
-	/**
-	 * Blob value.
-	 */
-	public static final class BlobValue extends Value {
-		private final Object object;
-		private byte[] bytes;
-
-		public BlobValue(Object object) {
-			this.object = object;
-		}
-
-		@Override
-		public int estimateSize() throws AerospikeException.Serialize {
-			bytes = serialize(object);
-			return bytes.length;
-		}
-
-		public static byte[] serialize(Object val) {
-			if (DisableSerializer) {
-				throw new AerospikeException("Object serializer has been disabled");
-			}
-
-			try (ByteArrayOutputStream bstream = new ByteArrayOutputStream()) {
-				try (ObjectOutputStream ostream = new ObjectOutputStream(bstream)) {
-					ostream.writeObject(val);
-				}
-				return bstream.toByteArray();
-			}
-			catch (Throwable e) {
-				throw new AerospikeException.Serialize(e);
-			}
-		}
-
-		@Override
-		public int write(byte[] buffer, int offset) {
-			System.arraycopy(bytes, 0, buffer, offset, bytes.length);
-			return bytes.length;
-		}
-
-		@Override
-		public void pack(Packer packer) {
-			packer.packBlob(object);
-		}
-
-		@Override
-		public void validateKeyType() {
-			throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: jblob");
-		}
-
-		@Override
-		public int getType() {
-			return ParticleType.JBLOB;
-		}
-
-		@Override
-		public Object getObject() {
-			return object;
-		}
-
-		@Override
-		public LuaValue getLuaValue(LuaInstance instance) {
-			return LuaString.valueOf(bytes);
-		}
-
-		@Override
-		public String toString() {
-			return Buffer.bytesToHexString(bytes);
-		}
-
-		@Override
-		public boolean equals(Object other) {
-			return (other != null &&
-				this.getClass().equals(other.getClass()) &&
-				this.object.equals(((BlobValue)other).object));
-		}
-
-		@Override
-		public int hashCode() {
-			return object.hashCode();
-		}
-	}
-
 	/**
 	 * GeoJSON value.
 	 */

programming_language: Java
filename: Buffer.java
change_type: ModificationType.MODIFY
diff: @@ -16,8 +16,6 @@
  */
 package com.aerospike.client.command;
 
-import java.io.ByteArrayInputStream;
-import java.io.ObjectInputStream;
 import java.math.BigInteger;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
@@ -69,9 +67,6 @@ public final class Buffer {
 		case ParticleType.BLOB:
 			return Arrays.copyOfRange(buf, offset, offset+len);
 
-		case ParticleType.JBLOB:
-			return Buffer.bytesToObject(buf, offset, len);
-
 		case ParticleType.GEOJSON:
 			return Buffer.bytesToGeoJSON(buf, offset, len);
 
@@ -297,25 +292,6 @@ public final class Buffer {
 		return sb.toString();
 	}
 
-	public static Object bytesToObject(byte[] buf, int offset, int length) {
-		if (length <= 0) {
-			return null;
-		}
-
-		if (Value.DisableDeserializer) {
-			throw new AerospikeException.Serialize("Object deserializer has been disabled");
-		}
-
-		try (ByteArrayInputStream bastream = new ByteArrayInputStream(buf, offset, length)) {
-			try (ObjectInputStream oistream = new ObjectInputStream(bastream)) {
-				return oistream.readObject();
-			}
-		}
-		catch (Throwable e) {
-			throw new AerospikeException.Serialize(e);
-		}
-	}
-
 	public static Value bytesToLongValue(byte[] buf, int offset, int len) {
 		long val = 0;
 

programming_language: Java
filename: ParticleType.java
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2021 Aerospike, Inc.
+ * Copyright 2012-2023 Aerospike, Inc.
  *
  * Portions may be licensed to Aerospike, Inc. under one or more contributor
  * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
@@ -17,23 +17,14 @@
 package com.aerospike.client.command;
 
 /**
- * Bin type for byte[] values.
+ * Server particle types.
  */
 public final class ParticleType {
-	// Server particle types. Unsupported types are commented out.
 	public static final int NULL = 0;
 	public static final int INTEGER = 1;
 	public static final int DOUBLE = 2;
 	public static final int STRING = 3;
 	public static final int BLOB = 4;
-	//public static final int TIMESTAMP = 5;
-	//public static final int DIGEST = 6;
-	public static final int JBLOB = 7;
-	//public static final int CSHARP_BLOB = 8;
-	//public static final int PYTHON_BLOB = 9;
-	//public static final int RUBY_BLOB = 10;
-	//public static final int PHP_BLOB = 11;
-	//public static final int ERLANG_BLOB = 12;
 	public static final int BOOL = 17;
 	public static final int HLL = 18;
 	public static final int MAP = 19;

programming_language: Java
filename: LuaInstance.java
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2021 Aerospike, Inc.
+ * Copyright 2012-2023 Aerospike, Inc.
  *
  * Portions may be licensed to Aerospike, Inc. under one or more contributor
  * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
@@ -171,10 +171,6 @@ public final class LuaInstance {
 			System.arraycopy(buf, offset, blob, 0, len);
 			return new LuaBytes(this, blob);
 
-		case ParticleType.JBLOB:
-			Object object = Buffer.bytesToObject(buf, offset, len);
-			return new LuaJavaBlob(object);
-
 		case ParticleType.LIST: {
 			LuaUnpacker unpacker = new LuaUnpacker(this, buf, offset, len);
 			return unpacker.unpackList();

programming_language: Java
filename: LuaJavaBlob.java
change_type: ModificationType.DELETE
diff: @@ -1,30 +0,0 @@
-/*
- * Copyright 2012-2021 Aerospike, Inc.
- *
- * Portions may be licensed to Aerospike, Inc. under one or more contributor
- * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.aerospike.client.lua;
-
-import org.luaj.vm2.LuaUserdata;
-
-public final class LuaJavaBlob extends LuaUserdata implements LuaData {
-
-	public LuaJavaBlob(Object object) {
-		super(object);
-	}
-
-	public Object luaToObject() {
-		return m_instance;
-	}
-}

programming_language: unknown
filename: LuaUnpacker.java
change_type: ModificationType.MODIFY
diff: @@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2021 Aerospike, Inc.
+ * Copyright 2012-2023 Aerospike, Inc.
  *
  * Portions may be licensed to Aerospike, Inc. under one or more contributor
  * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
@@ -46,11 +46,6 @@ public class LuaUnpacker extends Unpacker<LuaValue> {
 		return new LuaList(instance, value);
 	}
 
-	@Override
-	protected LuaValue getJavaBlob(Object value) {
-		return new LuaJavaBlob(value);
-	}
-
 	@Override
 	protected LuaBytes getBlob(byte[] value) {
 		return new LuaBytes(instance, value);

programming_language: Java
filename: Packer.java
change_type: ModificationType.MODIFY
diff: @@ -27,7 +27,6 @@ import java.util.UUID;
 
 import com.aerospike.client.AerospikeException;
 import com.aerospike.client.Value;
-import com.aerospike.client.Value.BlobValue;
 import com.aerospike.client.cdt.MapOrder;
 import com.aerospike.client.command.Buffer;
 import com.aerospike.client.command.ParticleType;
@@ -206,13 +205,6 @@ public final class Packer {
 		packByteArray(b, offset, length);
 	}
 
-	public void packBlob(Object val) {
-		byte[] bytes = BlobValue.serialize(val);
-		packByteArrayBegin(bytes.length + 1);
-		packByte(ParticleType.JBLOB);
-		packByteArray(bytes, 0, bytes.length);
-	}
-
 	public void packGeoJSON(String val) {
 		byte[] buffer = Buffer.stringToUtf8(val);
 		packByteArrayBegin(buffer.length + 1);
@@ -323,7 +315,7 @@ public final class Packer {
 			return;
 		}
 
-		packBlob(obj);
+		throw new AerospikeException("Unsupported type: " + obj.getClass().getName());
 	}
 
 	public void packByteBuffer(ByteBuffer bb) {

programming_language: Java
filename: Unpacker.java
change_type: ModificationType.MODIFY
diff: @@ -16,9 +16,7 @@
  */
 package com.aerospike.client.util;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.io.ObjectInputStream;
 import java.nio.ByteBuffer;
 import java.util.AbstractMap;
 import java.util.ArrayList;
@@ -234,21 +232,6 @@ public abstract class Unpacker<T> {
 			val = getString(Buffer.utf8ToString(buffer, offset, count));
 			break;
 
-		case ParticleType.JBLOB:
-			if (Value.DisableDeserializer) {
-				throw new AerospikeException.Serialize("Object deserializer has been disabled");
-			}
-
-			try (ByteArrayInputStream bastream = new ByteArrayInputStream(buffer, offset, count)) {
-				try (ObjectInputStream oistream = new ObjectInputStream(bastream)) {
-					val = getJavaBlob(oistream.readObject());
-				}
-			}
-			catch (Throwable e) {
-				throw new AerospikeException.Serialize(e);
-			}
-			break;
-
 		case ParticleType.GEOJSON:
 			val = getGeoJSON(Buffer.utf8ToString(buffer, offset, count));
 			break;
@@ -451,7 +434,6 @@ public abstract class Unpacker<T> {
 
 	protected abstract T getMap(Map<T,T> value);
 	protected abstract T getList(List<T> value);
-	protected abstract T getJavaBlob(Object value);
 	protected abstract T getBlob(byte[] value);
 	protected abstract T getString(String value);
 	protected abstract T getLong(long value);
@@ -498,11 +480,6 @@ public abstract class Unpacker<T> {
 			return value;
 		}
 
-		@Override
-		protected Object getJavaBlob(Object value) {
-			return value;
-		}
-
 		@Override
 		protected Object getBlob(byte[] value) {
 			return value;

programming_language: Java
filename: Main.java
change_type: ModificationType.MODIFY
diff: @@ -48,7 +48,6 @@ public class Main extends JPanel {
 		"Prepend",
 		"Batch",
 		"Generation",
-		"Serialize",
 		"Expire",
 		"Touch",
 		"StoreKey",

programming_language: Java
filename: OperateMap.java
change_type: ModificationType.MODIFY
diff: @@ -151,23 +151,23 @@ public class OperateMap extends Example {
 		client.delete(params.writePolicy, key);
 
 		List<Value> l1 = new ArrayList<Value>();
-		l1.add(Value.get(new GregorianCalendar(2018, 1, 1).getTime()));
+		l1.add(Value.get(new GregorianCalendar(2018, 1, 1).getTimeInMillis()));
 		l1.add(Value.get(1));
 
 		List<Value> l2 = new ArrayList<Value>();
-		l2.add(Value.get(new GregorianCalendar(2018, 1, 2).getTime()));
+		l2.add(Value.get(new GregorianCalendar(2018, 1, 2).getTimeInMillis()));
 		l2.add(Value.get(2));
 
 		List<Value> l3 = new ArrayList<Value>();
-		l3.add(Value.get(new GregorianCalendar(2018, 2, 1).getTime()));
+		l3.add(Value.get(new GregorianCalendar(2018, 2, 1).getTimeInMillis()));
 		l3.add(Value.get(3));
 
 		List<Value> l4 = new ArrayList<Value>();
-		l4.add(Value.get(new GregorianCalendar(2018, 2, 2).getTime()));
+		l4.add(Value.get(new GregorianCalendar(2018, 2, 2).getTimeInMillis()));
 		l4.add(Value.get(4));
 
 		List<Value> l5 = new ArrayList<Value>();
-		l5.add(Value.get(new GregorianCalendar(2018, 2, 5).getTime()));
+		l5.add(Value.get(new GregorianCalendar(2018, 2, 5).getTimeInMillis()));
 		l5.add(Value.get(5));
 
 		Map<Value,Value> inputMap = new HashMap<Value,Value>();
@@ -185,7 +185,7 @@ public class OperateMap extends Example {
 		console.info("Record: " + record);
 
 		List<Value> end = new ArrayList<Value>();
-		end.add(Value.get(new GregorianCalendar(2018, 2, 2).getTime()));
+		end.add(Value.get(new GregorianCalendar(2018, 2, 2).getTimeInMillis()));
 		end.add(Value.getAsNull());
 
 		// Delete values < end.

programming_language: Java
filename: Serialize.java
change_type: ModificationType.DELETE
diff: @@ -1,223 +0,0 @@
-/*
- * Copyright 2012-2023 Aerospike, Inc.
- *
- * Portions may be licensed to Aerospike, Inc. under one or more contributor
- * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.aerospike.examples;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import com.aerospike.client.AerospikeClient;
-import com.aerospike.client.Bin;
-import com.aerospike.client.Key;
-import com.aerospike.client.Record;
-import com.aerospike.client.Value;
-
-public class Serialize extends Example {
-
-	public Serialize(Console console) {
-		super(console);
-	}
-
-	/**
-	 * Write complex objects using serializer.
-	 */
-	@Override
-	public void runExample(AerospikeClient client, Parameters params) throws Exception {
-		testArray(client, params);
-		testList(client, params);
-		testComplex(client, params);
-	}
-
-	/**
-	 * Write array of integers using standard java serializer..
-	 */
-	public void testArray(AerospikeClient client, Parameters params) throws Exception {
-		Key key = new Key(params.namespace, params.set, "serialarraykey");
-
-		// Delete record if it already exists.
-		client.delete(params.writePolicy, key);
-
-		console.info("Initialize array");
-
-		int[] array = new int[10000];
-
-		for (int i = 0; i < 10000; i++) {
-			array[i] = i * i;
-		}
-
-		Bin bin = new Bin("serialbin", array);
-
-		// Do a test that pushes this complex object through the serializer
-		console.info("Write array using serializer.");
-		client.put(params.writePolicy, key, bin);
-
-		console.info("Read array using serializer.");
-		Record record = client.get(params.policy, key, bin.name);
-
-		if (record == null) {
-			throw new Exception(String.format(
-				"Failed to get: namespace=%s set=%s key=%s",
-				key.namespace, key.setName, key.userKey));
-		}
-
-		int[] received;
-
-		try {
-			received = (int[])record.getValue(bin.name);
-		}
-		catch (Exception e) {
-			throw new Exception(String.format(
-				"Failed to parse returned value: namespace=%s set=%s key=%s bin=%s",
-				key.namespace, key.setName, key.userKey, bin.name));
-		}
-
-		if (received.length != 10000) {
-			throw new Exception(String.format(
-				"Array length mismatch: Expected=%d Received=%d", 10000, received.length));
-		}
-
-		for (int i = 0; i < 10000; i++) {
-			if (received[i] != i * i) {
-				throw new Exception(String.format(
-					"Mismatch: index=%d expected=%d received=%d", i, i*i, received[i]));
-			}
-		}
-
-		console.info("Read array successful.");
-	}
-
-	/**
-	 * Write list using standard java serializer.
-	 */
-	public void testList(AerospikeClient client, Parameters params) throws Exception {
-		Key key = new Key(params.namespace, params.set, "seriallistkey");
-
-		// Delete record if it already exists.
-		client.delete(params.writePolicy, key);
-
-		console.info("Initialize list");
-
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("string1");
-		list.add("string2");
-		list.add("string3");
-
-		Bin bin = new Bin("serialbin", (Object)list);
-
-		console.info("Write list using serializer.");
-		client.put(params.writePolicy, key, bin);
-
-		console.info("Read list using serializer.");
-		Record record = client.get(params.policy, key, bin.name);
-
-		if (record == null) {
-			throw new Exception(String.format(
-				"Failed to get: namespace=%s set=%s key=%s",
-				key.namespace, key.setName, key.userKey));
-		}
-
-		List<?> received;
-
-		try {
-			received = (List<?>) record.getValue(bin.name);
-		}
-		catch (Exception e) {
-			throw new Exception(String.format(
-				"Failed to parse returned value: namespace=%s set=%s key=%s bin=%s",
-				key.namespace, key.setName, key.userKey, bin.name));
-		}
-
-		if (received.size() != 3) {
-			throw new Exception(String.format(
-				"Array length mismatch: Expected=%d Received=%d", 3, received.size()));
-		}
-
-		for (int i = 0; i < received.size(); i++) {
-			String expected = "string" + (i + 1);
-			if (! received.get(i).equals(expected)) {
-				Object obj = received.get(i);
-				throw new Exception(String.format(
-					"Mismatch: index=%d expected=%s received=%s", i, expected, obj));
-			}
-		}
-
-		console.info("Read list successful.");
-	}
-
-	/**
-	 * Write complex object using standard java serializer.
-	 */
-	public void testComplex(AerospikeClient client, Parameters params) throws Exception {
-		Key key = new Key(params.namespace, params.set, "serialcomplexkey");
-
-		// Delete record if it already exists.
-		client.delete(params.writePolicy, key);
-
-		console.info("Initialize complex object");
-
-		ArrayList<Object> inner = new ArrayList<Object>();
-		inner.add("string2");
-		inner.add(8);
-
-		HashMap<Object,Object> innerMap = new HashMap<Object,Object>();
-		innerMap.put("a", 1);
-		innerMap.put(2, "b");
-		innerMap.put("list", inner);
-
-		ArrayList<Object> list = new ArrayList<Object>();
-		list.add("string1");
-		list.add(4);
-		list.add(inner);
-		list.add(innerMap);
-
-		Bin bin = new Bin("complexbin", new Value.BlobValue(list));
-
-		console.info("Write complex object using serializer.");
-		client.put(params.writePolicy, key, bin);
-
-		console.info("Read complex object using serializer.");
-		Record record = client.get(params.policy, key, bin.name);
-
-		if (record == null) {
-			throw new Exception(String.format(
-				"Failed to get: namespace=%s set=%s key=%s",
-				key.namespace, key.setName, key.userKey));
-		}
-
-		Object received;
-
-		try {
-			received = (List<?>) record.getValue(bin.name);
-		}
-		catch (Exception e) {
-			throw new Exception(String.format(
-				"Failed to parse returned value: namespace=%s set=%s key=%s bin=%s",
-				key.namespace, key.setName, key.userKey, bin.name));
-		}
-
-		if (received != null && received.equals(list)) {
-			console.info("Data matched: namespace=%s set=%s key=%s bin=%s value=%s",
-				key.namespace, key.setName, key.userKey, bin.name, received);
-		}
-		else {
-			console.error("Data mismatch");
-			console.error("Expected " + list);
-			console.error("Received " + received);
-		}
-		console.info("Read complex object successful.");
-	}
-}

programming_language: unknown
filename: SuiteSync.java
change_type: ModificationType.MODIFY
diff: @@ -46,7 +46,6 @@ import com.aerospike.test.sync.basic.TestOperateMap;
 import com.aerospike.test.sync.basic.TestPutGet;
 import com.aerospike.test.sync.basic.TestReplace;
 import com.aerospike.test.sync.basic.TestScan;
-import com.aerospike.test.sync.basic.TestSerialize;
 import com.aerospike.test.sync.basic.TestServerInfo;
 import com.aerospike.test.sync.basic.TestTouch;
 import com.aerospike.test.sync.basic.TestUDF;
@@ -89,7 +88,6 @@ import com.aerospike.test.util.Args;
 	TestPutGet.class,
 	TestReplace.class,
 	TestScan.class,
-	TestSerialize.class,
 	TestServerInfo.class,
 	TestTouch.class,
 	TestUDF.class,

programming_language: Java
filename: TestAdd.java
change_type: ModificationType.MODIFY
diff: @@ -28,6 +28,7 @@ import com.aerospike.client.Key;
 import com.aerospike.client.Operation;
 import com.aerospike.client.Record;
 import com.aerospike.client.ResultCode;
+import com.aerospike.client.Value;
 import com.aerospike.client.util.Version;
 import com.aerospike.test.sync.TestSync;
 
@@ -71,7 +72,7 @@ public class TestAdd extends TestSync {
 		// Delete record if it already exists.
 		client.delete(null, key);
 
-		Bin bin = new Bin(binName, (Long)null);
+		Bin bin = new Bin(binName, Value.get((Object)null));
 
 		AerospikeException ae = assertThrows(AerospikeException.class, new ThrowingRunnable() {
 			public void run() {

programming_language: Java
filename: TestSerialize.java
change_type: ModificationType.DELETE
diff: @@ -1,166 +0,0 @@
-/*
- * Copyright 2012-2023 Aerospike, Inc.
- *
- * Portions may be licensed to Aerospike, Inc. under one or more contributor
- * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.aerospike.test.sync.basic;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.junit.Test;
-
-import com.aerospike.client.Bin;
-import com.aerospike.client.Key;
-import com.aerospike.client.Record;
-import com.aerospike.client.Value;
-import com.aerospike.test.sync.TestSync;
-
-public class TestSerialize extends TestSync {
-	private static final String binName = "serialbin";
-
-	@Test
-	public void serializeArray() {
-		Key key = new Key(args.namespace, args.set, "serialarraykey");
-
-		// Delete record if it already exists.
-		client.delete(null, key);
-
-		int[] array = new int[10000];
-
-		for (int i = 0; i < 10000; i++) {
-			array[i] = i * i;
-		}
-
-		Bin bin = new Bin(binName, array);
-
-		// Do a test that pushes this complex object through the serializer
-		client.put(null, key, bin);
-
-		Record record = client.get(null, key, bin.name);
-		assertRecordFound(key, record);
-
-		int[] received = null;
-
-		try {
-			received = (int[])record.getValue(bin.name);
-		}
-		catch (Exception e) {
-			fail("Failed to parse returned value: namespace=" + key.namespace + " set=" + key.setName +
-				 " key=" + key.userKey + " bin=" + bin.name);
-		}
-
-		assertNotNull(received);
-		assertEquals(10000, received.length);
-
-		for (int i = 0; i < 10000; i++) {
-			if (received[i] != i * i) {
-				fail("Mismatch: index=" + i + " expected=" + (i*i) + " received=" + received[i]);
-			}
-		}
-	}
-
-	@Test
-	public void serializeList() {
-		Key key = new Key(args.namespace, args.set, "seriallistkey");
-
-		// Delete record if it already exists.
-		client.delete(null, key);
-
-		ArrayList<String> list = new ArrayList<String>();
-		list.add("string1");
-		list.add("string2");
-		list.add("string3");
-
-		Bin bin = new Bin(binName, (Object)list);
-
-		client.put(null, key, bin);
-
-		Record record = client.get(null, key, bin.name);
-		assertRecordFound(key, record);
-
-		List<?> received = null;
-
-		try {
-			received = (List<?>) record.getValue(bin.name);
-		}
-		catch (Exception e) {
-			fail("Failed to parse returned value: namespace=" + key.namespace + " set=" + key.setName +
-				 " key=" + key.userKey + " bin=" + bin.name);
-		}
-
-		assertNotNull(received);
-		assertEquals(3, received.size());
-		int max = received.size();
-
-		for (int i = 0; i < max; i++) {
-			String expected = "string" + (i + 1);
-			if (! received.get(i).equals(expected)) {
-				Object obj = received.get(i);
-				fail("Mismatch: index=" + i + " expected=" + expected + " received=" + obj);
-			}
-		}
-	}
-
-	@Test
-	public void serializeComplex() {
-		Key key = new Key(args.namespace, args.set, "serialcomplexkey");
-
-		// Delete record if it already exists.
-		client.delete(null, key);
-
-		ArrayList<Object> inner = new ArrayList<Object>();
-		inner.add("string2");
-		inner.add(8);
-
-		HashMap<Object,Object> innerMap = new HashMap<Object,Object>();
-		innerMap.put("a", 1);
-		innerMap.put(2, "b");
-		innerMap.put("list", inner);
-
-		ArrayList<Object> list = new ArrayList<Object>();
-		list.add("string1");
-		list.add(4);
-		list.add(inner);
-		list.add(innerMap);
-
-		Bin bin = new Bin("complexbin", new Value.BlobValue(list));
-
-		client.put(null, key, bin);
-
-		Record record = client.get(null, key, bin.name);
-		assertRecordFound(key, record);
-
-		Object received = null;
-
-		try {
-			received = (List<?>) record.getValue(bin.name);
-		}
-		catch (Exception e) {
-			fail("Failed to parse returned value: namespace=" + key.namespace + " set=" + key.setName +
-				 " key=" + key.userKey + " bin=" + bin.name);
-		}
-
-		if (received == null || ! received.equals(list)) {
-			fail("Data mismatch" + System.lineSeparator() +
-				"Expected " + list + System.lineSeparator() +
-				"Received " + received);
-		}
-	}
-}

programming_language: unknown