Apple's Core Foundation framework has various object-creation functions
which allocate and initialise memory for opaque objects. These
functions can, of course, fail due to OOM at any time. So their direct
use requires malloc-like return value checking.
Add thin wrappers around some Core Foundation functions which abort on
failure - similar to the nfmalloc() wrapper for malloc(). In
particular, the nfstrtocf() wraps CFStringCreateWithCString() and
nfcftostr() wraps CFStringGetCString().
The wrappers are similar to nfstrdup() with the added functionality of
converting between C strings and Core Foundation string objects. They
operate exclusively with UTF-8 C strings. Ideally the encoding would
be configured to match the default C string encoding, but there isn't
a good way to do that, so just assume the default encoding is at least
UTF-8 compatible (which it should be anyway on any sane system).
---
src/common.h | 9 +++++++++
src/drv_imap.c | 11 ++++++++---
src/util.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/src/common.h b/src/common.h
index 38521b685bc3..52fc811b0906 100644
--- a/src/common.h
+++ b/src/common.h
@@ -21,6 +21,10 @@
#include <string.h>
#include <time.h>
+#ifdef HAVE_MACOS_KEYCHAIN
+#include <CoreFoundation/CFString.h>
+#endif /* HAVE_MACOS_KEYCHAIN */
+
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
@@ -298,6 +302,11 @@ int ATTR_PRINTFLIKE(3, 4) nfsnprintf( char *buf, int blen,
const char *fmt, ...
void ATTR_NORETURN oob( void );
void ATTR_NORETURN oom( void );
+#ifdef HAVE_MACOS_KEYCHAIN
+CFStringRef nfstrtocf( const char *str );
+char *nfcftostr( CFStringRef str );
+#endif /* HAVE_MACOS_KEYCHAIN */
+
int map_name( const char *arg, int argl, char **result, uint reserve, const
char *in, const char *out );
int mkdir_p( char *path, int len );
diff --git a/src/drv_imap.c b/src/drv_imap.c
index bbc6f43b290c..01ca24cc34ec 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -2361,9 +2361,14 @@ search_macos_keychain( const char *host, const char
*user )
NULL ); // itemRef
if (ret != errSecSuccess) {
CFStringRef errmsg = SecCopyErrorMessageString( ret, NULL );
- error( "Looking up Keychain failed: %s\n",
- CFStringGetCStringPtr( errmsg, kCFStringEncodingUTF8 ) );
- CFRelease( errmsg );
+ if (errmsg) {
+ char *errstr = nfcftostr( errmsg );
+ error( "Looking up Keychain failed: %s\n", errstr );
+ free( errstr );
+ CFRelease( errmsg );
+ } else {
+ error( "Looking up Keychain failed: Unknown error\n" );
+ }
return NULL;
}
diff --git a/src/util.c b/src/util.c
index c110188d4fac..8dfeb3a6efd6 100644
--- a/src/util.c
+++ b/src/util.c
@@ -703,6 +703,38 @@ nfasprintf( char **str, const char *fmt, ... )
return ret;
}
+#ifdef HAVE_MACOS_KEYCHAIN
+/*
+ * Basically just nfstrdup() but the new string can be used with Apple's Core
+ * Foundation framework. The given str must be non-NULL and UTF-8 encoded.
The
+ * caller retains ownership of the returned reference.
+ */
+CFStringRef
+nfstrtocf( const char *str )
+{
+ CFStringRef ret = CFStringCreateWithCString(
+ kCFAllocatorDefault, str, kCFStringEncodingUTF8 );
+ if (!ret)
+ oom();
+ return ret;
+}
+
+/*
+ * Reverse of nfstrtocf; duplicates a Core Foundation string object as a C
+ * string encoded with UTF-8. The given str must be non-NULL. The caller
+ * retains ownership of the returned string.
+ */
+char *
+nfcftostr( CFStringRef str )
+{
+ CFIndex len = CFStringGetLength( str ); // Length in UTF-16
+ size_t max_size = len * sizeof(UInt16) + sizeof(char);
+ char *ret = nfmalloc( max_size );
+ CFStringGetCString( str, ret, max_size, kCFStringEncodingUTF8 );
+ return ret;
+}
+#endif /* HAVE_MACOS_KEYCHAIN */
+
/*
static struct passwd *
cur_user( void )
--
2.50.1 (Apple Git-155)
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel