Skip to content

Commit 9cc5bad

Browse files
authored
Fix Objective-C static analysis warnings. (microsoft#20417)
Replace most usages of [NSString stringWithUTF8String:] with checked helper function. The issue is that the former can return nil.
1 parent dfd4bce commit 9cc5bad

File tree

7 files changed

+44
-16
lines changed

7 files changed

+44
-16
lines changed

cmake/onnxruntime_providers_coreml.cmake

+4-2
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,12 @@ endif()
126126
if (APPLE)
127127
file(GLOB
128128
onnxruntime_providers_coreml_objcc_srcs CONFIGURE_DEPENDS
129-
"${ONNXRUNTIME_ROOT}/core/providers/coreml/model/model.h"
130-
"${ONNXRUNTIME_ROOT}/core/providers/coreml/model/model.mm"
131129
"${ONNXRUNTIME_ROOT}/core/providers/coreml/model/host_utils.h"
132130
"${ONNXRUNTIME_ROOT}/core/providers/coreml/model/host_utils.mm"
131+
"${ONNXRUNTIME_ROOT}/core/providers/coreml/model/model.h"
132+
"${ONNXRUNTIME_ROOT}/core/providers/coreml/model/model.mm"
133+
"${ONNXRUNTIME_ROOT}/core/providers/coreml/model/objc_str_utils.h"
134+
"${ONNXRUNTIME_ROOT}/core/providers/coreml/model/objc_str_utils.mm"
133135
)
134136
else()
135137
# add the Model implementation that uses the protobuf types but excludes any actual CoreML dependencies

objectivec/ort_checkpoint.mm

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <variant>
99
#import "cxx_api.h"
1010

11+
#import "cxx_utils.h"
1112
#import "error_utils.h"
1213

1314
NS_ASSUME_NONNULL_BEGIN
@@ -73,7 +74,7 @@ - (nullable NSString*)getStringPropertyWithName:(NSString*)name error:(NSError**
7374
try {
7475
Ort::Property value = [self CXXAPIOrtCheckpoint].GetProperty(name.UTF8String);
7576
if (std::string* str = std::get_if<std::string>(&value)) {
76-
return [NSString stringWithUTF8String:str->c_str()];
77+
return utils::toNSString(str->c_str());
7778
}
7879
ORT_CXX_API_THROW("Property is not a string.", ORT_INVALID_ARGUMENT);
7980
}

objectivec/ort_session.mm

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <vector>
88

99
#import "cxx_api.h"
10+
#import "cxx_utils.h"
1011
#import "error_utils.h"
1112
#import "ort_enums_internal.h"
1213
#import "ort_env_internal.h"
@@ -198,8 +199,7 @@ - (BOOL)runWithInputs:(NSDictionary<NSString*, ORTValue*>*)inputs
198199

199200
for (size_t i = 0; i < nameCount; ++i) {
200201
auto name = getName(i, allocator);
201-
NSString* nameNsstr = [NSString stringWithUTF8String:name.get()];
202-
NSAssert(nameNsstr != nil, @"nameNsstr must not be nil");
202+
NSString* nameNsstr = utils::toNSString(name.get());
203203
[result addObject:nameNsstr];
204204
}
205205

onnxruntime/core/providers/coreml/model/host_utils.mm

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "core/platform/env.h"
55
#include "core/providers/coreml/model/host_utils.h"
6+
#include "core/providers/coreml/model/objc_str_utils.h"
67

78
#import <Foundation/Foundation.h>
89

@@ -36,7 +37,7 @@ int32_t CoreMLVersion() {
3637
#if !defined(NDEBUG)
3738
std::string path_override = Env::Default().GetEnvironmentVar(kOverrideModelOutputDirectoryEnvVar);
3839
if (!path_override.empty()) {
39-
NSString* ns_path_override = [NSString stringWithUTF8String:path_override.c_str()];
40+
NSString* ns_path_override = Utf8StringToNSString(path_override.c_str());
4041
temporary_directory_url = [NSURL fileURLWithPath:ns_path_override isDirectory:YES];
4142
}
4243
#endif

onnxruntime/core/providers/coreml/model/model.mm

+4-10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "core/providers/coreml/builders/helper.h"
2424
#include "core/providers/coreml/coreml_provider_factory.h"
2525
#include "core/providers/coreml/model/host_utils.h"
26+
#include "core/providers/coreml/model/objc_str_utils.h"
2627
#include "core/providers/coreml/shape_utils.h"
2728

2829
// force the linker to create a dependency on the CoreML framework so that in MAUI usage we don't need
@@ -33,13 +34,6 @@
3334
using namespace onnxruntime::coreml;
3435

3536
namespace {
36-
// Converts a UTF8 const char* to an NSString. Throws on failure.
37-
NSString* _Nonnull Utf8StringToNSString(const char* utf8_str) {
38-
NSString* result = [NSString stringWithUTF8String:utf8_str];
39-
ORT_ENFORCE(result != nil, "NSString conversion failed.");
40-
return result;
41-
}
42-
4337
/**
4438
* Computes the static output shape used to allocate the output tensor.
4539
* `inferred_shape` is the inferred shape known at model compile time. It may contain dynamic dimensions (-1).
@@ -165,7 +159,7 @@ Status CreateInputFeatureProvider(const std::unordered_map<std::string, OnnxTens
165159
(error != nil) ? MakeString(", error: ", [[error localizedDescription] UTF8String]) : "");
166160

167161
MLFeatureValue* feature_value = [MLFeatureValue featureValueWithMultiArray:multi_array];
168-
NSString* feature_name = Utf8StringToNSString(name.c_str());
162+
NSString* feature_name = util::Utf8StringToNSString(name.c_str());
169163
feature_dictionary[feature_name] = feature_value;
170164
}
171165

@@ -270,7 +264,7 @@ - (instancetype)initWithPath:(const std::string&)path
270264
logger:(const logging::Logger&)logger
271265
coreml_flags:(uint32_t)coreml_flags {
272266
if (self = [super init]) {
273-
coreml_model_path_ = [NSString stringWithUTF8String:path.c_str()];
267+
coreml_model_path_ = util::Utf8StringToNSString(path.c_str());
274268
logger_ = &logger;
275269
coreml_flags_ = coreml_flags;
276270
}
@@ -371,7 +365,7 @@ - (Status)predict:(const std::unordered_map<std::string, OnnxTensorData>&)inputs
371365

372366
for (const auto& [output_name, output_tensor_info] : outputs) {
373367
MLFeatureValue* output_value =
374-
[output_features featureValueForName:Utf8StringToNSString(output_name.c_str())];
368+
[output_features featureValueForName:util::Utf8StringToNSString(output_name.c_str())];
375369

376370
if (output_value == nil) {
377371
return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "output_features has no value for ", output_name);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#import <Foundation/Foundation.h>
7+
8+
namespace onnxruntime::coreml::util {
9+
10+
// Converts a UTF8 const char* to an NSString. Throws on failure.
11+
// Prefer this to directly calling [NSString stringWithUTF8String:] as that may return nil.
12+
NSString* _Nonnull Utf8StringToNSString(const char* _Nonnull utf8_str);
13+
14+
} // namespace onnxruntime::coreml::util
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#include "core/providers/coreml/model/objc_str_utils.h"
5+
6+
#include "core/common/common.h"
7+
8+
namespace onnxruntime::coreml::util {
9+
10+
NSString* _Nonnull Utf8StringToNSString(const char* _Nonnull utf8_str) {
11+
NSString* result = [NSString stringWithUTF8String:utf8_str];
12+
ORT_ENFORCE(result != nil, "NSString conversion failed.");
13+
return result;
14+
}
15+
16+
} // namespace onnxruntime::coreml::util

0 commit comments

Comments
 (0)