Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,7 @@ public static Object attribute2jdbcValue(final Object value, int sqlType) throws
if (value == null) {
return null;
}
try {
switch (sqlType) {
// Known conversions
case Types.DECIMAL:
Expand Down Expand Up @@ -948,6 +949,14 @@ public static Object attribute2jdbcValue(final Object value, int sqlType) throws
} else {
return Long.valueOf(value.toString());
}
default:
break;
}
} catch (NumberFormatException e) {
throw new ConnectorException("Value '" + value + "' is not valid for SQL type "
+ sqlType, e);
}
switch (sqlType) {
case Types.TIMESTAMP:
if (value instanceof String) {
return string2Timestamp((String) value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
* Portions Copyrighted 2026 3A Systems, LLC
*/
package org.identityconnectors.dbcommon;

import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;

import org.identityconnectors.framework.common.exceptions.ConnectorException;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import java.sql.Blob;
Expand Down Expand Up @@ -597,6 +599,26 @@ public void testAttribute2JdbcValue() throws SQLException {
assertEquals(true, actual);
}

/**
* A value that does not fit the target SQL type must fail with a
* ConnectorException naming the value and the type, not a bare
* NumberFormatException.
*/
@Test(expectedExceptions = ConnectorException.class)
public void testAttribute2JdbcValueRejectsMalformedDouble() throws SQLException {
SQLUtil.attribute2jdbcValue("not-a-number", Types.DOUBLE);
}

@Test(expectedExceptions = ConnectorException.class)
public void testAttribute2JdbcValueRejectsMalformedFloat() throws SQLException {
SQLUtil.attribute2jdbcValue("not-a-number", Types.FLOAT);
}

@Test(expectedExceptions = ConnectorException.class)
public void testAttribute2JdbcValueRejectsMalformedInteger() throws SQLException {
SQLUtil.attribute2jdbcValue("not-a-number", Types.INTEGER);
}

/**
* We need this helper class as InitialContextFactory class name value to
* Hashtable into InitialContext. We must use instantiable classname and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* ====================
*
* Portions Copyrighted 2012 ForgeRock AS
* Portions Copyrighted 2026 3A Systems, LLC
*
*/
package org.identityconnectors.contract.test;
Expand All @@ -35,6 +36,7 @@
import java.util.Set;

import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.contract.exceptions.ContractException;
import org.identityconnectors.contract.exceptions.ObjectNotFoundException;
import org.identityconnectors.framework.api.operations.APIOperation;
import org.identityconnectors.framework.api.operations.AuthenticationApiOp;
Expand Down Expand Up @@ -507,7 +509,12 @@ private long getLongTestParam(String name, long defaultValue) {
Object valueObject = getDataProvider().getTestSuiteAttribute(name,
TEST_NAME);
if(valueObject != null) {
longValue = Long.parseLong(valueObject.toString());
try {
longValue = Long.parseLong(valueObject.toString());
} catch (NumberFormatException e) {
throw new ContractException("Test suite attribute '" + name
+ "' is not a valid number: '" + valueObject + "'", e);
}
}
} catch (ObjectNotFoundException ex) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,13 @@ private static ConnectorInfoManager getRemoteManager(final DataProvider dataProv
host = System.getProperty("serverHost");
}
if (StringUtil.isNotBlank(System.getProperty("serverPort"))) {
port = Integer.parseInt(System.getProperty("serverPort"));
String serverPort = System.getProperty("serverPort");
try {
port = Integer.parseInt(serverPort);
} catch (NumberFormatException e) {
throw new ContractException("System property serverPort is not a valid port "
+ "number: '" + serverPort + "'", e);
}
}
if (StringUtil.isNotBlank(System.getProperty("serverKey"))) {
key = System.getProperty("serverKey");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
* Portions Copyrighted 2026 3A Systems, LLC
*/
package org.identityconnectors.framework.impl.serializer.xml;

Expand Down Expand Up @@ -180,7 +181,11 @@ private boolean decodeBoolean(String v) {
}

private byte decodeByte(String v) {
return Byte.decode(v);
try {
return Byte.decode(v);
} catch (NumberFormatException e) {
throw new ConnectorException("Malformed byte value on the wire: '" + v + "'", e);
}
}

private byte[] decodeByteArray(String base64) {
Expand All @@ -204,19 +209,35 @@ private Class<?> decodeClass(String type) {
}

private double decodeDouble(String val) {
return Double.parseDouble(val);
try {
return Double.parseDouble(val);
} catch (NumberFormatException e) {
throw new ConnectorException("Malformed double value on the wire: '" + val + "'", e);
}
}

private float decodeFloat(String val) {
return Float.parseFloat(val);
try {
return Float.parseFloat(val);
} catch (NumberFormatException e) {
throw new ConnectorException("Malformed float value on the wire: '" + val + "'", e);
}
}

private int decodeInt(String val) {
return Integer.parseInt(val);
try {
return Integer.parseInt(val);
} catch (NumberFormatException e) {
throw new ConnectorException("Malformed int value on the wire: '" + val + "'", e);
}
}

private long decodeLong(String val) {
return Long.parseLong(val);
try {
return Long.parseLong(val);
} catch (NumberFormatException e) {
throw new ConnectorException("Malformed long value on the wire: '" + val + "'", e);
}
}

private Object readObjectInternal() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions copyright [year] [name of copyright owner]".
*
* Copyright 2026 3A Systems, LLC.
*/
package org.identityconnectors.framework.impl.serializer.xml;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.identityconnectors.framework.common.serializer.SerializerUtil;
import org.testng.annotations.Test;

/**
* A peer sending a corrupted numeric value on the wire must fail with a
* ConnectorException naming what failed to decode, not a bare
* NumberFormatException with no indication of where in the stream it came
* from.
*/
public class XmlObjectDecoderTest {

@Test
public void decodesAValidInt() {
String xml = SerializerUtil.serializeXmlObject(Integer.valueOf(42), true);
assertEquals(SerializerUtil.deserializeXmlObject(xml, true), Integer.valueOf(42));
}

@Test
public void rejectsAMalformedInt() {
String xml = corrupt(SerializerUtil.serializeXmlObject(Integer.valueOf(42), true), "42");
try {
SerializerUtil.deserializeXmlObject(xml, true);
fail("Expected the malformed value to be rejected");
} catch (ConnectorException expected) {
// expected: not a bare NumberFormatException
}
}

@Test
public void rejectsAMalformedLong() {
String xml = corrupt(SerializerUtil.serializeXmlObject(Long.valueOf(42L), true), "42");
try {
SerializerUtil.deserializeXmlObject(xml, true);
fail("Expected the malformed value to be rejected");
} catch (ConnectorException expected) {
// expected
}
}

@Test
public void rejectsAMalformedDouble() {
String xml = corrupt(SerializerUtil.serializeXmlObject(Double.valueOf(4.2), true), "4.2");
try {
SerializerUtil.deserializeXmlObject(xml, true);
fail("Expected the malformed value to be rejected");
} catch (ConnectorException expected) {
// expected
}
}

/**
* Replaces the encoded numeric payload of a valid wire message with a
* non-numeric string, so the rest of the document stays schema-valid and
* only the value under test is corrupted.
*/
private static String corrupt(String validXml, String encodedValue) {
String corrupted = validXml.replace(">" + encodedValue + "<", ">not-a-number<");
if (corrupted.equals(validXml)) {
throw new IllegalStateException("Could not locate '" + encodedValue
+ "' in the serialized XML to corrupt it: " + validXml);
}
return corrupted;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* Portions Copyrighted 2026 3A Systems, LLC
*/

package org.forgerock.openicf.framework.client;
Expand All @@ -39,6 +40,7 @@
import org.identityconnectors.common.Assertions;
import org.identityconnectors.common.StringUtil;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.identityconnectors.framework.api.RemoteFrameworkConnectionInfo;

public class RemoteWSFrameworkConnectionInfo {
Expand Down Expand Up @@ -136,7 +138,13 @@ public void loadSystemProxy() {
String host = System.getProperty(PROXY_HOST);
if (host != null) {
proxyHost = host;
proxyPort = Integer.valueOf(System.getProperty(PROXY_PORT, "80"));
String port = System.getProperty(PROXY_PORT, "80");
try {
proxyPort = Integer.valueOf(port);
} catch (NumberFormatException e) {
throw new ConnectorException("System property " + PROXY_PORT
+ " is not a valid port number: '" + port + "'", e);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions copyright [year] [name of copyright owner]".
*
* Copyright 2026 3A Systems, LLC.
*/
package org.forgerock.openicf.framework.client;

import static org.testng.Assert.fail;

import java.net.URI;

import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;

public class RemoteWSFrameworkConnectionInfoTest {

@AfterMethod
public void clearProxyProperties() {
System.clearProperty(RemoteWSFrameworkConnectionInfo.PROXY_HOST);
System.clearProperty(RemoteWSFrameworkConnectionInfo.PROXY_PORT);
}

/**
* A typo in -Dhttp.proxyPort must fail with a clear ConnectorException at
* startup rather than a bare NumberFormatException.
*/
@Test
public void loadSystemProxyRejectsAMalformedPort() {
System.setProperty(RemoteWSFrameworkConnectionInfo.PROXY_HOST, "proxy.example.com");
System.setProperty(RemoteWSFrameworkConnectionInfo.PROXY_PORT, "not-a-number");

RemoteWSFrameworkConnectionInfo.Builder builder =
RemoteWSFrameworkConnectionInfo.newBuilder().setRemoteURI(
URI.create("ws://127.0.0.1:8759/openicf"));
RemoteWSFrameworkConnectionInfo info = builder.build();
try {
info.loadSystemProxy();
fail("Expected the malformed proxy port to be rejected");
} catch (ConnectorException expected) {
// expected: not a bare NumberFormatException
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* Portions Copyrighted 2026 3A Systems, LLC
*/
package org.identityconnectors.ldap;

Expand Down Expand Up @@ -144,19 +145,19 @@ public javax.naming.directory.Attribute getLdapAttribute() {
// Static helpers

public static boolean isScopeGlobal(String scope) {
return ((Integer.parseInt(scope) & SCOPE_GLOBAL) == SCOPE_GLOBAL);
return ((ADLdapUtil.parseADInteger(scope) & SCOPE_GLOBAL) == SCOPE_GLOBAL);
}

public static boolean isScopeDomainLocal(String scope) {
return ((Integer.parseInt(scope) & SCOPE_DOMAIN_LOCAL) == SCOPE_DOMAIN_LOCAL);
return ((ADLdapUtil.parseADInteger(scope) & SCOPE_DOMAIN_LOCAL) == SCOPE_DOMAIN_LOCAL);
}

public static boolean isScopeUniversal(String scope) {
return ((Integer.parseInt(scope) & SCOPE_UNIVERSAL) == SCOPE_UNIVERSAL);
return ((ADLdapUtil.parseADInteger(scope) & SCOPE_UNIVERSAL) == SCOPE_UNIVERSAL);
}

public static boolean isTypeSecurity(String type) {
return ((Integer.parseInt(type) & TYPE_SECURITY) == TYPE_SECURITY);
return ((ADLdapUtil.parseADInteger(type) & TYPE_SECURITY) == TYPE_SECURITY);
}

public static String getType(String type){
Expand Down Expand Up @@ -187,13 +188,13 @@ public static ADGroupType createADGroupType(LdapConnection conn, String id) thro
NamingEnumeration<SearchResult> entries = conn.getInitialContext().search(context, String.format("%s=%s", LdapConstants.MS_GUID_ATTR, guidStringtoByteString(id)), controls);
if (entries.hasMore()) {
SearchResult res = entries.next();
int gt = Integer.parseInt(res.getAttributes().get(GROUPTYPE).get().toString());
int gt = ADLdapUtil.parseADInteger(res.getAttributes().get(GROUPTYPE).get().toString());
return new ADGroupType(gt);
}
}
} else if (isDNAttribute(conn.getConfiguration().getUidAttribute())) {
Attributes attrs = conn.getInitialContext().getAttributes(escapeDNValueOfJNDIReservedChars(id), new String[]{GROUPTYPE});
int gt = Integer.parseInt(attrs.get(GROUPTYPE).get().toString());
int gt = ADLdapUtil.parseADInteger(attrs.get(GROUPTYPE).get().toString());
return new ADGroupType(gt);
}
throw new NamingException("Entry not found");
Expand Down
Loading
Loading