| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 | 
							- /*
 
-  * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
 
-  *
 
-  * Licensed under the OpenSSL license (the "License").  You may not use
 
-  * this file except in compliance with the License.  You can obtain a copy
 
-  * in the file LICENSE in the source distribution or at
 
-  * https://www.openssl.org/source/license.html
 
-  */
 
- # if defined(__linux) || defined(__sun) || defined(__hpux)
 
- /*
 
-  * Following definition aliases fopen to fopen64 on above mentioned
 
-  * platforms. This makes it possible to open and sequentially access files
 
-  * larger than 2GB from 32-bit application. It does not allow to traverse
 
-  * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit
 
-  * platform permits that, not with fseek/ftell. Not to mention that breaking
 
-  * 2GB limit for seeking would require surgery to *our* API. But sequential
 
-  * access suffices for practical cases when you can run into large files,
 
-  * such as fingerprinting, so we can let API alone. For reference, the list
 
-  * of 32-bit platforms which allow for sequential access of large files
 
-  * without extra "magic" comprise *BSD, Darwin, IRIX...
 
-  */
 
- #  ifndef _FILE_OFFSET_BITS
 
- #   define _FILE_OFFSET_BITS 64
 
- #  endif
 
- # endif
 
- #include "e_os.h"
 
- #include "internal/cryptlib.h"
 
- #if !defined(OPENSSL_NO_STDIO)
 
- # include <stdio.h>
 
- # ifdef __DJGPP__
 
- #  include <unistd.h>
 
- # endif
 
- FILE *openssl_fopen(const char *filename, const char *mode)
 
- {
 
-     FILE *file = NULL;
 
- # if defined(_WIN32) && defined(CP_UTF8)
 
-     int sz, len_0 = (int)strlen(filename) + 1;
 
-     DWORD flags;
 
-     /*
 
-      * 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, (flags = MB_ERR_INVALID_CHARS),
 
-                                   filename, len_0, NULL, 0)) > 0 ||
 
-         (GetLastError() == ERROR_INVALID_FLAGS &&
 
-          (sz = MultiByteToWideChar(CP_UTF8, (flags = 0),
 
-                                    filename, len_0, NULL, 0)) > 0)
 
-         ) {
 
-         WCHAR wmode[8];
 
-         WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
 
-         if (MultiByteToWideChar(CP_UTF8, flags,
 
-                                 filename, len_0, wfilename, sz) &&
 
-             MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1,
 
-                                 wmode, OSSL_NELEM(wmode)) &&
 
-             (file = _wfopen(wfilename, wmode)) == NULL &&
 
-             (errno == ENOENT || errno == EBADF)
 
-             ) {
 
-             /*
 
-              * 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);
 
-     }
 
- # elif defined(__DJGPP__)
 
-     {
 
-         char *newname = NULL;
 
-         if (pathconf(filename, _PC_NAME_MAX) <= 12) {  /* 8.3 file system? */
 
-             char *iterator;
 
-             char lastchar;
 
-             if ((newname = OPENSSL_malloc(strlen(filename) + 1)) == NULL) {
 
-                 CRYPTOerr(CRYPTO_F_OPENSSL_FOPEN, ERR_R_MALLOC_FAILURE);
 
-                 return NULL;
 
-             }
 
-             for (iterator = newname, lastchar = '\0';
 
-                 *filename; filename++, iterator++) {
 
-                 if (lastchar == '/' && filename[0] == '.'
 
-                     && filename[1] != '.' && filename[1] != '/') {
 
-                     /* Leading dots are not permitted in plain DOS. */
 
-                     *iterator = '_';
 
-                 } else {
 
-                     *iterator = *filename;
 
-                 }
 
-                 lastchar = *filename;
 
-             }
 
-             *iterator = '\0';
 
-             filename = newname;
 
-         }
 
-         file = fopen(filename, mode);
 
-         OPENSSL_free(newname);
 
-     }
 
- # else
 
-     file = fopen(filename, mode);
 
- # endif
 
-     return file;
 
- }
 
- #else
 
- void *openssl_fopen(const char *filename, const char *mode)
 
- {
 
-     return NULL;
 
- }
 
- #endif
 
 
  |