aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/bio/bss_file.c
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2010-04-28 20:02:28 +0000
committerAndy Polyakov <appro@openssl.org>2010-04-28 20:02:28 +0000
commitbb92e2c89b4aee9e1d1bb27a4a6da3817c66d005 (patch)
tree4dc5ead294f252b520c215bd698a4813ecfc934b /crypto/bio/bss_file.c
parent5e19ee96f6c0d59e5e63c8366e7989c3ae26852f (diff)
downloadopenssl-bb92e2c89b4aee9e1d1bb27a4a6da3817c66d005.tar.gz
bss_file.c: refine UTF-8 logic on Windows.
Diffstat (limited to 'crypto/bio/bss_file.c')
-rw-r--r--crypto/bio/bss_file.c53
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)
{