diff --git a/cpp/include/Ice/Properties.h b/cpp/include/Ice/Properties.h index ad69368182f..cfa5141c981 100644 --- a/cpp/include/Ice/Properties.h +++ b/cpp/include/Ice/Properties.h @@ -85,15 +85,16 @@ namespace Ice * Get a property as an integer. If the property is not set, 0 is returned. * @param key The property key. * @return The property value interpreted as an integer. + * @throws PropertyException If the property value is not a valid integer. * @see #setProperty */ - int getPropertyAsInt(std::string_view key) noexcept; + int getPropertyAsInt(std::string_view key); /** * Get an Ice property as an integer. If the property is not set, its default value is returned. * @param key The property key. * @return The property value interpreted as an integer, or the default value. - * @throws std::invalid_argument If the property is not a known Ice property. + * @throws PropertyException If the property is not a known Ice property or the value is not a valid integer. * @see #setProperty */ int getIcePropertyAsInt(std::string_view key); @@ -103,9 +104,10 @@ namespace Ice * @param key The property key. * @param value The default value to use if the property does not exist. * @return The property value interpreted as an integer, or the default value. + * @throws PropertyException If the property value is not a valid integer. * @see #setProperty */ - int getPropertyAsIntWithDefault(std::string_view key, int value) noexcept; + int getPropertyAsIntWithDefault(std::string_view key, int value); /** * Get a property as a list of strings. The strings must be separated by whitespace or comma. If the property is @@ -127,7 +129,7 @@ namespace Ice * can be written as O'Reilly, "O'Reilly" or 'O\'Reilly'. * @param key The property key. * @return The property value interpreted as list of strings, or the default value. - * @throws std::invalid_argument If the property is not a known Ice property. + * @throws PropertyException If the property is not a known Ice property. * @see #setProperty */ StringSeq getIcePropertyAsList(std::string_view key); diff --git a/cpp/src/Ice/Properties.cpp b/cpp/src/Ice/Properties.cpp index bce42147c69..d067685e26e 100644 --- a/cpp/src/Ice/Properties.cpp +++ b/cpp/src/Ice/Properties.cpp @@ -202,7 +202,7 @@ Ice::Properties::getPropertyWithDefault(string_view key, string_view value) noex } int32_t -Ice::Properties::getPropertyAsInt(string_view key) noexcept +Ice::Properties::getPropertyAsInt(string_view key) { return getPropertyAsIntWithDefault(key, 0); } @@ -224,21 +224,21 @@ Ice::Properties::getIcePropertyAsInt(string_view key) } int32_t -Ice::Properties::getPropertyAsIntWithDefault(string_view key, int32_t value) noexcept +Ice::Properties::getPropertyAsIntWithDefault(string_view key, int32_t value) { lock_guard lock(_mutex); map::iterator p = _properties.find(key); if (p != _properties.end()) { - int32_t val = value; p->second.used = true; istringstream v(p->second.value); if (!(v >> value) || !v.eof()) { - Warning out(getProcessLogger()); - out << "numeric property " << key << " set to non-numeric value, defaulting to " << val; - return val; + throw PropertyException( + __FILE__, + __LINE__, + "property '" + string{key} + "' has an invalid integer value: '" + p->second.value + "'"); } } diff --git a/cpp/test/Ice/properties/Client.cpp b/cpp/test/Ice/properties/Client.cpp index 1d56967d44d..0353bc8e11d 100644 --- a/cpp/test/Ice/properties/Client.cpp +++ b/cpp/test/Ice/properties/Client.cpp @@ -215,6 +215,21 @@ Client::run(int, char**) test(properties->getProperty("Ice.MessageSizeMax") == "20"); cout << "ok" << endl; } + + { + cout << "testing that trying to read a non-numeric value as an int throws... " << flush; + Ice::PropertiesPtr properties = Ice::createProperties(); + properties->setProperty("Foo", "bar"); + try + { + properties->getPropertyAsInt("Foo"); + test(false); + } + catch (const Ice::PropertyException&) + { + } + cout << "ok" << endl; + } } DEFINE_TEST(Client) diff --git a/csharp/src/Ice/Properties.cs b/csharp/src/Ice/Properties.cs index 11fe463c010..3da5d3c0ebb 100644 --- a/csharp/src/Ice/Properties.cs +++ b/csharp/src/Ice/Properties.cs @@ -169,6 +169,7 @@ public string getPropertyWithDefault(string key, string value) /// /// The property key. /// The property value interpreted as an integer. + /// Thrown if the property value is not a valid integer. public int getPropertyAsInt(string key) => getPropertyAsIntWithDefault(key, 0); /// @@ -177,6 +178,8 @@ public string getPropertyWithDefault(string key, string value) /// /// The property key. /// The property value interpreted as an integer, or the default value. + /// Thrown if the property is not a known Ice property or the value is not a + /// valid integer. public int getIcePropertyAsInt(string key) { string defaultValueString = getDefaultProperty(key); @@ -196,6 +199,7 @@ public int getIcePropertyAsInt(string key) /// The property key. /// The default value to use if the property does not exist. /// The property value interpreted as an integer, or the default value. + /// Thrown if the property value is not a valid integer. public int getPropertyAsIntWithDefault(string key, int value) { lock (_mutex) @@ -211,8 +215,7 @@ public int getPropertyAsIntWithDefault(string key, int value) } catch (FormatException) { - Util.getProcessLogger().warning($"numeric property {key} set to non-numeric value, defaulting to {value}"); - return value; + throw new PropertyException($"property '{key}' has an invalid integer value: '{pv.value}'"); } } } diff --git a/csharp/test/Ice/properties/Client.cs b/csharp/test/Ice/properties/Client.cs index dca8781a166..08ccd4f8a5c 100644 --- a/csharp/test/Ice/properties/Client.cs +++ b/csharp/test/Ice/properties/Client.cs @@ -186,6 +186,21 @@ public override void run(string[] args) test(properties.getIceProperty("Ice.MessageSizeMax") == "20"); Console.Out.WriteLine("ok"); } + + { + Console.Out.Write("testing that trying to read a non-numeric value as an int throws... "); + var properties = new Ice.Properties(); + properties.setProperty("Foo", "bar"); + try + { + properties.getIcePropertyAsInt("Foo"); + test(false); + } + catch (Ice.PropertyException) + { + } + Console.Out.WriteLine("ok"); + } } public static Task Main(string[] args) => diff --git a/java/src/com.zeroc.ice/src/main/java/com/zeroc/Ice/Properties.java b/java/src/com.zeroc.ice/src/main/java/com/zeroc/Ice/Properties.java index 0ac457e3545..00002ce2c3b 100644 --- a/java/src/com.zeroc.ice/src/main/java/com/zeroc/Ice/Properties.java +++ b/java/src/com.zeroc.ice/src/main/java/com/zeroc/Ice/Properties.java @@ -204,6 +204,7 @@ public synchronized String getPropertyWithDefault(String key, String value) { * * @param key The property key. * @return The property value interpreted as an integer. + * @throws PropertyException Raised if the property value is not a valid integer. * @see #setProperty */ public int getPropertyAsInt(String key) { @@ -215,6 +216,8 @@ public int getPropertyAsInt(String key) { * * @param key The property key. * @return The property value interpreted as an integer, or the default value. + * @throws PropertyException Raised if the property is not a known Ice property or the value is + * not a valid integer. * @see #setProperty */ public synchronized int getIcePropertyAsInt(String key) { @@ -234,6 +237,7 @@ public synchronized int getIcePropertyAsInt(String key) { * @param key The property key. * @param value The default value to use if the property does not exist. * @return The property value interpreted as an integer, or the default value. + * @throws PropertyException Raised if the property value is not a valid integer. * @see #setProperty */ public synchronized int getPropertyAsIntWithDefault(String key, int value) { @@ -244,12 +248,8 @@ public synchronized int getPropertyAsIntWithDefault(String key, int value) { try { return Integer.parseInt(pv.value); } catch (NumberFormatException ex) { - Util.getProcessLogger() - .warning( - "numeric property " - + key - + " set to non-numeric value, defaulting to " - + value); + throw new PropertyException( + "property '" + key + "' has an invalid integer value: '" + pv.value + "'"); } } diff --git a/java/test/src/main/java/test/Ice/properties/Client.java b/java/test/src/main/java/test/Ice/properties/Client.java index c0493087922..a2fed5bf4cb 100644 --- a/java/test/src/main/java/test/Ice/properties/Client.java +++ b/java/test/src/main/java/test/Ice/properties/Client.java @@ -185,6 +185,21 @@ public void run(String[] args) { test(properties.getIceProperty("Ice.MessageSizeMax").equals("20")); System.out.println("ok"); } + + { + System.out.print( + "testing that trying to read a non-numeric value as an int throws... "); + System.out.flush(); + + Properties properties = new Properties(); + properties.setProperty("Foo", "bar"); + try { + properties.getIcePropertyAsInt("Foo"); + test(false); + } catch (PropertyException ex) { + } + System.out.println("ok"); + } } private static final String configPath = "./config/\u4E2D\u56FD_client.config"; diff --git a/js/src/Ice/Properties.d.ts b/js/src/Ice/Properties.d.ts index 2295c1e5671..63bc8a823f0 100644 --- a/js/src/Ice/Properties.d.ts +++ b/js/src/Ice/Properties.d.ts @@ -45,6 +45,7 @@ declare module "ice" { * * @param key - The property key. * @returns The property value interpreted as an integer. + * @throws {@link PropertyException} - Thrown if the property value is not a valid integer. * * @see {@link setProperty} */ @@ -55,6 +56,8 @@ declare module "ice" { * * @param key - The property key. * @returns The property value interpreted as an integer. + * @throws {@link PropertyException} - Thrown if the property is not a known Ice property or the value is + * not a valid integer. * * @see {@link setProperty} */ @@ -64,12 +67,13 @@ declare module "ice" { * Get a property as an integer. If the property is not set, the given default value is returned. * * @param key The property key. - * @param value The default value to use if the property does not exist. + * @param defaultValue The default value to use if the property does not exist. * @returns The property value interpreted as an integer, or the default value. + * @throws {@link PropertyException} - Thrown if the property value is not a valid integer. * * @see {@link setProperty} */ - getPropertyAsIntWithDefault(key: string, value: number): number; + getPropertyAsIntWithDefault(key: string, defaultValue: number): number; /** * Retrieves a property value as a list of strings. The strings must be separated by whitespace or commas. diff --git a/js/src/Ice/Properties.js b/js/src/Ice/Properties.js index 7ac9ab9afaf..537b718156b 100644 --- a/js/src/Ice/Properties.js +++ b/js/src/Ice/Properties.js @@ -64,17 +64,22 @@ export class Properties { let defaultValue = 0; if (defaultValueString != "") { defaultValue = parseInt(defaultValueString); + DEV: console.assert(!isNaN(defaultValue)); } return this.getPropertyAsIntWithDefault(key, defaultValue); } - getPropertyAsIntWithDefault(key, value) { + getPropertyAsIntWithDefault(key, defaultValue) { const pv = this._properties.get(key); if (pv !== undefined) { pv.used = true; - return parseInt(pv.value); - } else { + const value = parseInt(pv.value); + if (isNaN(value)) { + throw new PropertyException(`property '${key}' has an invalid integer value: '${pv.value}'`); + } return value; + } else { + return defaultValue; } } diff --git a/js/test/Ice/properties/Client.ts b/js/test/Ice/properties/Client.ts index 68b2643dd21..25593e0c124 100644 --- a/js/test/Ice/properties/Client.ts +++ b/js/test/Ice/properties/Client.ts @@ -154,6 +154,19 @@ export class Client extends TestHelper { test(properties.getIceProperty("Ice.MessageSizeMax") == "20"); out.writeLine("ok"); } + + { + out.write("testing that trying to read a non-numeric value as an int throws... "); + const properties = Ice.createProperties(); + try { + properties.setProperty("Foo", "bar"); + properties.getPropertyAsInt("Foo"); + test(false); + } catch (ex) { + test(ex instanceof Ice.PropertyException); + } + out.writeLine("ok"); + } } async run(args: string[]) { diff --git a/matlab/test/Ice/properties/Client.m b/matlab/test/Ice/properties/Client.m index b9da71365b7..aa820d8afb2 100644 --- a/matlab/test/Ice/properties/Client.m +++ b/matlab/test/Ice/properties/Client.m @@ -49,5 +49,15 @@ function client(args) end fprintf('ok\n'); + fprintf('testing that trying to read a non-numeric value as an int throws... '); + try + props.setProperty('Foo', 'bar'); + props.getPropertyAsInt('Foo'); + assert(false); + catch ex + assert(isa(ex, 'Ice.PropertyException')); + end + fprintf('ok\n'); + clear('classes'); % Avoids conflicts with tests that define the same symbols. end diff --git a/php/test/Ice/properties/Client.php b/php/test/Ice/properties/Client.php index aef1032a1f3..ac0f9cf5a53 100644 --- a/php/test/Ice/properties/Client.php +++ b/php/test/Ice/properties/Client.php @@ -23,7 +23,7 @@ function run($args) test($properties->getIceProperty("Ice.Trace.Protocol"), "1"); echo "ok\n"; - echo "testing ice properties with set default values..."; + echo "testing ice properties with set default values... "; $properties = Ice\createProperties(); $toStringMode = $properties->getIceProperty("Ice.ToStringMode"); @@ -37,7 +37,7 @@ function run($args) echo "ok\n"; - echo "testing ice properties with unset default values..."; + echo "testing ice properties with unset default values... "; $properties = Ice\createProperties(); $stringValue = $properties->getIceProperty("Ice.Admin.Router"); @@ -52,8 +52,8 @@ function run($args) echo "ok\n"; echo "testing load properties exception... "; + $properties = Ice\createProperties(); try { - $properties = Ice\createProperties(); $properties->load("./config/xxxx.config"); test(False); } catch (\Ice\LocalException $ex) { @@ -61,14 +61,24 @@ function run($args) } echo "ok\n"; - echo "testing that getting an unknown ice property throws an exception..."; + echo "testing that getting an unknown ice property throws an exception... "; + $properties = Ice\createProperties(); try { - $properties = Ice\createProperties(); $properties->getIceProperty("Ice.UnknownProperty"); test(False); } catch (\Ice\PropertyException $ex) { test($ex->getMessage() == "unknown Ice property: Ice.UnknownProperty"); } echo "ok\n"; + + echo "testing that trying to read a non-numeric value as an int throws... "; + $properties = Ice\createProperties(); + try { + $properties->setProperty("Foo", "bar"); + $properties->getPropertyAsInt("Foo"); + test(False); + } catch (\Ice\PropertyException $ex) { + } + echo "ok\n"; } } diff --git a/python/test/Ice/properties/Client.py b/python/test/Ice/properties/Client.py index 1c42557c57a..35ea3b4b5fc 100644 --- a/python/test/Ice/properties/Client.py +++ b/python/test/Ice/properties/Client.py @@ -121,3 +121,17 @@ def run(sef, args): except Ice.PropertyException: pass print("ok") + + sys.stdout.write( + "testing that trying to read a non-numeric value as an int throws... " + ) + sys.stdout.flush() + + properties = Ice.createProperties() + properties.setProperty("Test", "foo") + try: + properties.getPropertyAsInt("Test") + test(False) + except Ice.PropertyException: + pass + print("ok") diff --git a/ruby/test/Ice/properties/Client.rb b/ruby/test/Ice/properties/Client.rb index f38d82bf83d..9e0ca28cfa4 100644 --- a/ruby/test/Ice/properties/Client.rb +++ b/ruby/test/Ice/properties/Client.rb @@ -92,8 +92,8 @@ def run(args) puts "ok" print "testing that getting an unknown ice property throws an exception..." + properties = Ice.createProperties(args) begin - properties = Ice.createProperties(args) properties.getIceProperty("Ice.UnknownProperty") test(false) rescue Ice::PropertyException => ex @@ -101,5 +101,15 @@ def run(args) end puts "ok" + print "testing that trying to read a non-numeric value as an int throws... " + properties = Ice.createProperties(args) + begin + properties.setProperty("Foo", "bar") + properties.getPropertyAsInt("Foo") + test(false) + rescue Ice::PropertyException => ex + end + puts "ok" + end end diff --git a/scripts/tests/Ice/properties.py b/scripts/tests/Ice/properties.py index 14536d26a2f..6da63ead7c2 100644 --- a/scripts/tests/Ice/properties.py +++ b/scripts/tests/Ice/properties.py @@ -27,4 +27,14 @@ def setup(self, current): ) -PropertiesTestSuite(__name__, [ClientTestCase(client=Client(args=["{testdir}"]))]) +PropertiesTestSuite( + __name__, + [ClientTestCase(client=Client(args=["{testdir}"]))], + options={ + "ipv6": [False], + "compress": [False], + "protocol": ["tcp"], + "serialize": [False], + "mx": [False], + }, +) diff --git a/swift/src/Ice/CommunicatorI.swift b/swift/src/Ice/CommunicatorI.swift index cb0f88590c9..bcf6209d647 100644 --- a/swift/src/Ice/CommunicatorI.swift +++ b/swift/src/Ice/CommunicatorI.swift @@ -13,14 +13,14 @@ class CommunicatorI: LocalObject, Communicator { init(handle: ICECommunicator, initData: InitializationData) { defaultsAndOverrides = DefaultsAndOverrides(handle: handle) self.initData = initData - let num = initData.properties!.getIcePropertyAsInt("Ice.ClassGraphDepthMax") - if num < 1 || num > 0x7FFF_FFFF { - classGraphDepthMax = 0x7FFF_FFFF - } else { - classGraphDepthMax = num + do { + classGraphDepthMax = try initData.properties!.getIcePropertyAsInt("Ice.ClassGraphDepthMax") + precondition(classGraphDepthMax >= 1 && classGraphDepthMax <= 0x7FFF_FFFF, "Ice.ClassGraphDepthMax must be >= 0 and <= 0x7FFF_FFFF") + traceSlicing = try initData.properties!.getIcePropertyAsInt("Ice.Trace.Slicing") > 0 + acceptClassCycles = try initData.properties!.getIcePropertyAsInt("Ice.AcceptClassCycles") > 0 + } catch { + fatalError("\(error)") } - traceSlicing = initData.properties!.getIcePropertyAsInt("Ice.Trace.Slicing") > 0 - acceptClassCycles = initData.properties!.getIcePropertyAsInt("Ice.AcceptClassCycles") > 0 super.init(handle: handle) } diff --git a/swift/src/Ice/Properties.swift b/swift/src/Ice/Properties.swift index 1a8581dfa36..de3ccbef4ff 100644 --- a/swift/src/Ice/Properties.swift +++ b/swift/src/Ice/Properties.swift @@ -30,27 +30,30 @@ public protocol Properties: AnyObject { func getPropertyWithDefault(key: String, value: String) -> String /// Get a property as an integer. If the property is not set, 0 is returned. + /// Throws PropertyException if the property value is not a valid integer. /// /// - parameter _: `String` The property key. /// /// - returns: `Int32` - The property value interpreted as an integer. - func getPropertyAsInt(_ key: String) -> Int32 + func getPropertyAsInt(_ key: String) throws -> Int32 /// Get an Ice property as an integer. If the property is not set,its default value is returned. + /// Throws PropertyException if the property value is not a valid integer. /// /// - parameter key: `String` The property key. /// /// - returns: `Int32` - The property value interpreted as an integer, or the default value. - func getIcePropertyAsInt(_ key: String) -> Int32 + func getIcePropertyAsInt(_ key: String) throws -> Int32 /// Get a property as an integer. If the property is not set, the given default value is returned. + /// Throws PropertyException if the property value is not a valid integer. /// /// - parameter key: `String` The property key. /// /// - parameter value: `Int32` The default value to use if the property does not exist. /// /// - returns: `Int32` - The property value interpreted as an integer, or the default value. - func getPropertyAsIntWithDefault(key: String, value: Int32) -> Int32 + func getPropertyAsIntWithDefault(key: String, value: Int32) throws -> Int32 /// Get a property as a list of strings. The strings must be separated by whitespace or comma. If the property is /// not set, an empty list is returned. The strings in the list can contain whitespace and commas if they are diff --git a/swift/src/Ice/PropertiesI.swift b/swift/src/Ice/PropertiesI.swift index c32a1c432a4..cef232bc2c1 100644 --- a/swift/src/Ice/PropertiesI.swift +++ b/swift/src/Ice/PropertiesI.swift @@ -15,16 +15,28 @@ class PropertiesI: LocalObject, Properties { handle.getPropertyWithDefault(key, value: value) } - public func getPropertyAsInt(_ key: String) -> Int32 { - handle.getPropertyAsInt(key) + public func getPropertyAsInt(_ key: String) throws -> Int32 { + return try autoreleasepool { + var value: Int32 = 0 + try handle.getPropertyAsInt(key, value: &value) + return value + } } - public func getIcePropertyAsInt(_ key: String) -> Int32 { - handle.getIcePropertyAsInt(key) + public func getIcePropertyAsInt(_ key: String) throws -> Int32 { + return try autoreleasepool { + var value: Int32 = 0 + try handle.getIcePropertyAsInt(key: key, value: &value) + return value + } } - public func getPropertyAsIntWithDefault(key: String, value: Int32) -> Int32 { - handle.getPropertyAsIntWithDefault(key: key, value: value) + public func getPropertyAsIntWithDefault(key: String, value defaultValue: Int32) throws -> Int32 { + return try autoreleasepool { + var value: Int32 = 0 + try handle.getPropertyAsIntWithDefault(key: key, defaultValue: defaultValue, value: &value) + return value + } } public func getPropertyAsList(_ key: String) -> StringSeq { diff --git a/swift/src/IceImpl/Properties.mm b/swift/src/IceImpl/Properties.mm index 5421083f7e9..a746ad1cfa4 100644 --- a/swift/src/IceImpl/Properties.mm +++ b/swift/src/IceImpl/Properties.mm @@ -27,19 +27,51 @@ - (NSString*)getPropertyWithDefault:(NSString*)key value:(NSString*)value return toNSString(self.properties->getPropertyWithDefault(fromNSString(key), fromNSString(value))); } -- (int32_t)getPropertyAsInt:(NSString*)key +- (BOOL)getPropertyAsInt:(NSString*)key value:(int32_t*)value error:(NSError**)error { - return self.properties->getPropertyAsInt(fromNSString(key)); + assert(value != nullptr); + try + { + *value = self.properties->getPropertyAsInt(fromNSString(key)); + return YES; + } + catch (...) + { + *error = convertException(std::current_exception()); + return NO; + } } -- (int32_t)getIcePropertyAsInt:(NSString*)key +- (BOOL)getIcePropertyAsInt:(NSString*)key value:(int32_t*)value error:(NSError**)error { - return self.properties->getIcePropertyAsInt(fromNSString(key)); + assert(value != nullptr); + try + { + *value = self.properties->getIcePropertyAsInt(fromNSString(key)); + return YES; + } + catch (...) + { + *error = convertException(std::current_exception()); + return NO; + } } -- (int32_t)getPropertyAsIntWithDefault:(NSString*)key value:(int32_t)value +- (BOOL)getPropertyAsIntWithDefault:(NSString*)key + defaultValue:(int32_t)defaultValue + value:(int32_t*)value + error:(NSError**)error { - return self.properties->getPropertyAsIntWithDefault(fromNSString(key), value); + try + { + *value = self.properties->getPropertyAsIntWithDefault(fromNSString(key), defaultValue); + return YES; + } + catch (...) + { + *error = convertException(std::current_exception()); + return NO; + } } - (NSArray*)getPropertyAsList:(NSString*)key diff --git a/swift/src/IceImpl/include/Properties.h b/swift/src/IceImpl/include/Properties.h index d0c2225a948..fea15030576 100644 --- a/swift/src/IceImpl/include/Properties.h +++ b/swift/src/IceImpl/include/Properties.h @@ -7,10 +7,15 @@ ICEIMPL_API @interface ICEProperties : ICELocalObject - (NSString*)getProperty:(NSString*)key; - (NSString*)getIceProperty:(NSString*)key; - (NSString*)getPropertyWithDefault:(NSString*)key value:(NSString*)value; -- (int32_t)getPropertyAsInt:(NSString*)key; -- (int32_t)getIcePropertyAsInt:(NSString*)key NS_SWIFT_NAME(getIcePropertyAsInt(_:)); -- (int32_t)getPropertyAsIntWithDefault:(NSString*)key - value:(int32_t)value NS_SWIFT_NAME(getPropertyAsIntWithDefault(key:value:)); +- (BOOL)getPropertyAsInt:(NSString*)key value:(int32_t*)value error:(NSError* _Nullable* _Nullable)error; +- (BOOL)getIcePropertyAsInt:(NSString*)key + value:(int32_t*)value + error:(NSError* _Nullable* _Nullable)error NS_SWIFT_NAME(getIcePropertyAsInt(key:value:)); +- (BOOL)getPropertyAsIntWithDefault:(NSString*)key + defaultValue:(int32_t)defaultValue + value:(int32_t*)value + error:(NSError* _Nullable* _Nullable)error + NS_SWIFT_NAME(getPropertyAsIntWithDefault(key:defaultValue:value:)); - (NSArray*)getPropertyAsList:(NSString* _Nonnull)key; - (NSArray*)getIcePropertyAsList:(NSString* _Nonnull)key NS_SWIFT_NAME(getIcePropertyAsList(_:)); - (NSArray*)getPropertyAsListWithDefault:(NSString* _Nonnull)key @@ -18,12 +23,13 @@ ICEIMPL_API @interface ICEProperties : ICELocalObject NS_SWIFT_NAME(getPropertyAsListWithDefault(key:value:)); - (NSDictionary*)getPropertiesForPrefix:(NSString* _Nonnull)prefix NS_SWIFT_NAME(getPropertiesForPrefix(_:)); -- (BOOL)setProperty:(NSString*)key value:(NSString*)value error:(NSError**)error; +- (BOOL)setProperty:(NSString*)key value:(NSString*)value error:(NSError* _Nullable* _Nullable)error; - (NSArray*)getCommandLineOptions; - (nullable NSArray*)parseCommandLineOptions:(NSString*)prefix options:(NSArray*)options error:(NSError* _Nullable* _Nullable)error; -- (nullable NSArray*)parseIceCommandLineOptions:(NSArray*)options error:(NSError**)error; +- (nullable NSArray*)parseIceCommandLineOptions:(NSArray*)options + error:(NSError* _Nullable* _Nullable)error; - (BOOL)load:(NSString*)file error:(NSError* _Nullable* _Nullable)error; - (ICEProperties*)clone; @end diff --git a/swift/test/Ice/admin/TestI.swift b/swift/test/Ice/admin/TestI.swift index dcb512ecda1..003d69ba6d1 100644 --- a/swift/test/Ice/admin/TestI.swift +++ b/swift/test/Ice/admin/TestI.swift @@ -98,7 +98,7 @@ class RemoteCommunicatorFactoryI: RemoteCommunicatorFactory { var initData = Ice.InitializationData() initData.properties = properties - if properties.getPropertyAsInt("NullLogger") > 0 { + if try properties.getPropertyAsInt("NullLogger") > 0 { initData.logger = NullLogger() } diff --git a/swift/test/Ice/info/AllTests.swift b/swift/test/Ice/info/AllTests.swift index 621a771fca7..b1fd785a22e 100644 --- a/swift/test/Ice/info/AllTests.swift +++ b/swift/test/Ice/info/AllTests.swift @@ -83,7 +83,7 @@ func allTests(_ helper: TestHelper) async throws { output.write("test object adapter endpoint information... ") do { - let host = communicator.getProperties().getIcePropertyAsInt("Ice.IPv6") != 0 ? "::1" : "127.0.0.1" + let host = try communicator.getProperties().getIcePropertyAsInt("Ice.IPv6") != 0 ? "::1" : "127.0.0.1" communicator.getProperties().setProperty( key: "TestAdapter.Endpoints", value: "tcp -h \"\(host)\" -t 15000:udp -h \"\(host)\"") diff --git a/swift/test/Ice/objects/TestI.swift b/swift/test/Ice/objects/TestI.swift index 0ecf961c7c5..032a00d97bf 100644 --- a/swift/test/Ice/objects/TestI.swift +++ b/swift/test/Ice/objects/TestI.swift @@ -159,7 +159,7 @@ class InitialI: Initial { func acceptsClassCycles(current: Ice.Current) async throws -> Bool { let properties = current.adapter.getCommunicator().getProperties() - return properties.getIcePropertyAsInt("Ice.AcceptClassCycles") > 0 + return try properties.getIcePropertyAsInt("Ice.AcceptClassCycles") > 0 } func getD1(d1: D1?, current _: Ice.Current) async throws -> D1? { diff --git a/swift/test/Ice/optional/AllTests.swift b/swift/test/Ice/optional/AllTests.swift index c2896092521..8576316e624 100644 --- a/swift/test/Ice/optional/AllTests.swift +++ b/swift/test/Ice/optional/AllTests.swift @@ -669,7 +669,7 @@ func allTests(_ helper: TestHelper) async throws -> InitialPrx { } output.writeLine("ok") - if communicator.getProperties().getIcePropertyAsInt("Ice.Default.SlicedFormat") > 0 { + if try communicator.getProperties().getIcePropertyAsInt("Ice.Default.SlicedFormat") > 0 { output.write("testing marshaling with unknown class slices... ") do { let c = C() diff --git a/swift/test/Ice/properties/Client.swift b/swift/test/Ice/properties/Client.swift index b048c1ea2dd..776c355f8b3 100644 --- a/swift/test/Ice/properties/Client.swift +++ b/swift/test/Ice/properties/Client.swift @@ -104,7 +104,7 @@ public class Client: TestHelperI { let toStringMode = properties.getIceProperty("Ice.ToStringMode") try test(toStringMode == "Unicode") - let closeTimeout = properties.getIcePropertyAsInt("Ice.Connection.Client.CloseTimeout") + let closeTimeout = try properties.getIcePropertyAsInt("Ice.Connection.Client.CloseTimeout") try test(closeTimeout == 10) let retryIntervals = properties.getIcePropertyAsList("Ice.RetryIntervals") @@ -120,7 +120,7 @@ public class Client: TestHelperI { let stringValue = properties.getIceProperty("Ice.Admin.Router") try test(stringValue == "") - let intValue = properties.getIcePropertyAsInt("Ice.Admin.Router") + let intValue = try properties.getIcePropertyAsInt("Ice.Admin.Router") try test(intValue == 0) let listValue = properties.getIcePropertyAsList("Ice.Admin.Router") @@ -146,5 +146,21 @@ public class Client: TestHelperI { output.writeLine("ok") } */ + + do { + output.write("testing that trying to read a non-numeric value as an int throws...") + let properties = Ice.createProperties() + + do { + // Cannot test in Swift since this generates a fatal error. + properties.setProperty(key: "Foo", value: "bar") + _ = try properties.getPropertyAsInt("Foo") + try test(false) + + } catch _ as PropertyException { + } + + output.writeLine("ok") + } } } diff --git a/swift/test/Ice/proxy/AllTests.swift b/swift/test/Ice/proxy/AllTests.swift index 36d8089c230..d440741cdfc 100644 --- a/swift/test/Ice/proxy/AllTests.swift +++ b/swift/test/Ice/proxy/AllTests.swift @@ -856,7 +856,7 @@ public func allTests(_ helper: TestHelper) async throws -> MyClassPrx { "test -e 1.1:opaque -e 1.1 -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==")! try test(communicator.proxyToString(p2) == "test -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 10000") - if communicator.getProperties().getIcePropertyAsInt("Ice.IPv6") == 0 { + if try communicator.getProperties().getIcePropertyAsInt("Ice.IPv6") == 0 { // Two legal TCP endpoints expressed as opaque endpoints p1 = try communicator.stringToProxy( "test -e 1.0:" + "opaque -e 1.0 -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==:" diff --git a/swift/test/Ice/udp/AllTests.swift b/swift/test/Ice/udp/AllTests.swift index fd43b265120..502849d5e72 100644 --- a/swift/test/Ice/udp/AllTests.swift +++ b/swift/test/Ice/udp/AllTests.swift @@ -83,7 +83,7 @@ public func allTests(_ helper: TestHelper) async throws { } try test(ret) - if communicator.getProperties().getIcePropertyAsInt("Ice.Override.Compress") == 0 { + if try communicator.getProperties().getIcePropertyAsInt("Ice.Override.Compress") == 0 { // // Only run this test if compression is disabled, the test expect fixed message size // to be sent over the wire. diff --git a/swift/test/TestCommon/TestCommon.swift b/swift/test/TestCommon/TestCommon.swift index 6a1d96158b8..768108a8312 100644 --- a/swift/test/TestCommon/TestCommon.swift +++ b/swift/test/TestCommon/TestCommon.swift @@ -101,7 +101,7 @@ open class TestHelperI: TestHelper { (prot == "") ? properties.getIceProperty("Ice.Default.Protocol") : prot s += " -p " - let port = properties.getPropertyAsIntWithDefault(key: "Test.BasePort", value: 12010) + num + let port = try! properties.getPropertyAsIntWithDefault(key: "Test.BasePort", value: 12010) + num s += String(port) return s } @@ -127,7 +127,7 @@ open class TestHelperI: TestHelper { } public func getTestPort(properties: Ice.Properties, num: Int32) -> Int32 { - return properties.getPropertyAsIntWithDefault(key: "Test.BasePort", value: 12010) + num + return try! properties.getPropertyAsIntWithDefault(key: "Test.BasePort", value: 12010) + num } public func createTestProperties(_ args: [String]) throws -> Ice.Properties {