diff options
author | Andy Polyakov <appro@openssl.org> | 2010-04-28 20:02:28 +0000 |
---|---|---|
committer | Andy Polyakov <appro@openssl.org> | 2010-04-28 20:02:28 +0000 |
commit | bb92e2c89b4aee9e1d1bb27a4a6da3817c66d005 (patch) | |
tree | 4dc5ead294f252b520c215bd698a4813ecfc934b /crypto | |
parent | 5e19ee96f6c0d59e5e63c8366e7989c3ae26852f (diff) | |
download | openssl-bb92e2c89b4aee9e1d1bb27a4a6da3817c66d005.tar.gz |
bss_file.c: refine UTF-8 logic on Windows.
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/bio/bss_file.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c index 3f458a0c7c..8bfa0bcd97 100644 --- a/crypto/bio/bss_file.c +++ b/crypto/bio/bss_file.c @@ -118,28 +118,45 @@ static BIO_METHOD methods_filep= BIO *BIO_new_file(const char *filename, const char *mode) { - BIO *ret; - FILE *file; + BIO *ret; + FILE *file=NULL; - file=fopen(filename,mode); #if defined(_WIN32) && defined(CP_UTF8) - if (file==NULL && errno==ENOENT) /* see if filename is UTF-8 encoded */ + int sz, len_0 = (int)strlen(filename)+1; + + /* + * Basically there are three cases to cover: a) filename is + * pure ASCII string; b) actual UTF-8 encoded string and + * c) locale-ized string, i.e. one containing 8-bit + * characters that are meaningful in current system locale. + * If filename is pure ASCII or real UTF-8 encoded string, + * MultiByteToWideChar succeeds and _wfopen works. If + * filename is locale-ized string, chances are that + * MultiByteToWideChar fails reporting + * ERROR_NO_UNICODE_TRANSLATION, in which case we fall + * back to fopen... + */ + if ((sz=MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, + filename,len_0,NULL,0))>0) { - int sz,len_0 = (int)strlen(filename)+1; - if ((sz=MultiByteToWideChar(CP_UTF8,0,filename,len_0, - NULL,0))>0) - { - WCHAR wmode[8]; - WCHAR *wfilename = _alloca(sz*sizeof(WCHAR)); - - if (MultiByteToWideChar(CP_UTF8,0,filename,len_0, - wfilename,sz) && - MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1, - wmode,sizeof(wmode)/sizeof(wmode[0])) - ) - file = _wfopen(wfilename,wmode); - } + WCHAR wmode[8]; + WCHAR *wfilename = _alloca(sz*sizeof(WCHAR)); + + if (MultiByteToWideChar(CP_UTF8,MB_ERR_INVALID_CHARS, + filename,len_0,wfilename,sz) && + MultiByteToWideChar(CP_UTF8,0,mode,strlen(mode)+1, + wmode,sizeof(wmode)/sizeof(wmode[0])) && + (file=_wfopen(wfilename,wmode))==NULL && errno==ENOENT + ) /* UTF-8 decode succeeded, but no file, filename + * could still have been locale-ized... */ + file = fopen(filename,mode); + } + else if (GetLastError()==ERROR_NO_UNICODE_TRANSLATION) + { + file = fopen(filename,mode); } +#else + file=fopen(filename,mode); #endif if (file == NULL) { |