summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2010-04-28 20:04:37 +0000
committerAndy Polyakov <appro@openssl.org>2010-04-28 20:04:37 +0000
commit336d1ee7337dbeb3dc4350e8fde26bc09db6d8d4 (patch)
tree9fc6855d77e5b71ffc5e669204c01d7e3f4c9a02
parentbed2b769f552229c3686d522c7602eb8977e3516 (diff)
bss_file.c: reserve for option to encode file name in UTF-8 on Windows
[from HEAD].
-rw-r--r--crypto/bio/bss_file.c43
-rw-r--r--doc/crypto/BIO_s_file.pod4
2 files changed, 44 insertions, 3 deletions
diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c
index ba4f8e9940..8bfa0bcd97 100644
--- a/crypto/bio/bss_file.c
+++ b/crypto/bio/bss_file.c
@@ -118,10 +118,47 @@ static BIO_METHOD methods_filep=
BIO *BIO_new_file(const char *filename, const char *mode)
{
- BIO *ret;
- FILE *file;
+ BIO *ret;
+ FILE *file=NULL;
+
+#if defined(_WIN32) && defined(CP_UTF8)
+ 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)
+ {
+ WCHAR wmode[8];
+ WCHAR *wfilename = _alloca(sz*sizeof(WCHAR));
- if ((file=fopen(filename,mode)) == NULL)
+ 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)
{
SYSerr(SYS_F_FOPEN,get_last_sys_error());
ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
diff --git a/doc/crypto/BIO_s_file.pod b/doc/crypto/BIO_s_file.pod
index b2a29263f4..188aea347d 100644
--- a/doc/crypto/BIO_s_file.pod
+++ b/doc/crypto/BIO_s_file.pod
@@ -76,6 +76,10 @@ normally be closed so the BIO_NOCLOSE flag should be set.
Because the file BIO calls the underlying stdio functions any quirks
in stdio behaviour will be mirrored by the corresponding BIO.
+On Windows BIO_new_files reserves for the filename argument to be
+UTF-8 encoded. In other words if you have to make it work in multi-
+lingual environment, encode file names in UTF-8.
+
=head1 EXAMPLES
File BIO "hello world":