- * [FFmpeg-devel] [PATCH v20 2/5] compat/w32dlfcn.h: Remove MAX_PATH limit and replace LoadLibraryExA with LoadLibraryExW
  2022-06-20 10:29 [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup() Nil Admirari
@ 2022-06-20 10:29 ` Nil Admirari
  2022-06-20 10:29 ` [FFmpeg-devel] [PATCH v20 3/5] fftools: Remove MAX_PATH limit and switch to UTF-8 versions of fopen() and getenv() Nil Admirari
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Nil Admirari @ 2022-06-20 10:29 UTC (permalink / raw)
  To: ffmpeg-devel
---
 compat/w32dlfcn.h     | 100 ++++++++++++++++++++++++++++++++----------
 libavcodec/mf_utils.h |   1 +
 2 files changed, 79 insertions(+), 22 deletions(-)
diff --git a/compat/w32dlfcn.h b/compat/w32dlfcn.h
index 52a94efafb..fb1aa1b72e 100644
--- a/compat/w32dlfcn.h
+++ b/compat/w32dlfcn.h
@@ -20,11 +20,40 @@
 #define COMPAT_W32DLFCN_H
 
 #ifdef _WIN32
+#include <stdint.h>
+
 #include <windows.h>
+
 #include "config.h"
-#if (_WIN32_WINNT < 0x0602) || HAVE_WINRT
+#include "libavutil/macros.h"
 #include "libavutil/wchar_filename.h"
-#endif
+
+static inline wchar_t *get_module_filename(HMODULE module)
+{
+    wchar_t *path = NULL, *new_path;
+    DWORD path_size = 0, path_len;
+
+    do {
+        path_size = path_size ? FFMIN(2 * path_size, INT16_MAX + 1) : MAX_PATH;
+        new_path = av_realloc_array(path, path_size, sizeof *path);
+        if (!new_path) {
+            av_free(path);
+            return NULL;
+        }
+        path = new_path;
+        // Returns path_size in case of insufficient buffer.
+        // Whether the error is set or not and whether the output
+        // is null-terminated or not depends on the version of Windows.
+        path_len = GetModuleFileNameW(module, path, path_size);
+    } while (path_len && path_size <= INT16_MAX && path_size <= path_len);
+
+    if (!path_len) {
+        av_free(path);
+        return NULL;
+    }
+    return path;
+}
+
 /**
  * Safe function used to open dynamic libs. This attempts to improve program security
  * by removing the current directory from the dll search path. Only dll's found in the
@@ -34,29 +63,53 @@
  */
 static inline HMODULE win32_dlopen(const char *name)
 {
+    wchar_t *name_w;
+    HMODULE module = NULL;
+    if (utf8towchar(name, &name_w))
+        name_w = NULL;
 #if _WIN32_WINNT < 0x0602
-    // Need to check if KB2533623 is available
+    // On Win7 and earlier we check if KB2533623 is available
     if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) {
-        HMODULE module = NULL;
-        wchar_t *path = NULL, *name_w = NULL;
-        DWORD pathlen;
-        if (utf8towchar(name, &name_w))
+        wchar_t *path = NULL, *new_path;
+        DWORD pathlen, pathsize, namelen;
+        if (!name_w)
             goto exit;
-        path = (wchar_t *)av_calloc(MAX_PATH, sizeof(wchar_t));
+        namelen = wcslen(name_w);
         // Try local directory first
-        pathlen = GetModuleFileNameW(NULL, path, MAX_PATH);
-        pathlen = wcsrchr(path, '\\') - path;
-        if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
+        path = get_module_filename(NULL);
+        if (!path)
+            goto exit;
+        new_path = wcsrchr(path, '\\');
+        if (!new_path)
             goto exit;
-        path[pathlen] = '\\';
+        pathlen = new_path - path;
+        pathsize = pathlen + namelen + 2;
+        new_path = av_realloc_array(path, pathsize, sizeof *path);
+        if (!new_path)
+            goto exit;
+        path = new_path;
         wcscpy(path + pathlen + 1, name_w);
         module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
         if (module == NULL) {
             // Next try System32 directory
-            pathlen = GetSystemDirectoryW(path, MAX_PATH);
-            if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
+            pathlen = GetSystemDirectoryW(path, pathsize);
+            if (!pathlen)
                 goto exit;
-            path[pathlen] = '\\';
+            // Buffer is not enough in two cases:
+            // 1. system directory + \ + module name
+            // 2. system directory even without the module name.
+            if (pathlen + namelen + 2 > pathsize) {
+                pathsize = pathlen + namelen + 2;
+                new_path = av_realloc_array(path, pathsize, sizeof *path);
+                if (!new_path)
+                    goto exit;
+                path = new_path;
+                // Query again to handle the case #2.
+                pathlen = GetSystemDirectoryW(path, pathsize);
+                if (!pathlen)
+                    goto exit;
+            }
+            path[pathlen] = L'\\';
             wcscpy(path + pathlen + 1, name_w);
             module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
         }
@@ -73,16 +126,19 @@ exit:
 #   define LOAD_LIBRARY_SEARCH_SYSTEM32        0x00000800
 #endif
 #if HAVE_WINRT
-    wchar_t *name_w = NULL;
-    int ret;
-    if (utf8towchar(name, &name_w))
+    if (!name_w)
         return NULL;
-    ret = LoadPackagedLibrary(name_w, 0);
-    av_free(name_w);
-    return ret;
+    module = LoadPackagedLibrary(name_w, 0);
 #else
-    return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
+#define LOAD_FLAGS (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32)
+    /* filename may be be in CP_ACP */
+    if (!name_w)
+        return LoadLibraryExA(name, NULL, LOAD_FLAGS);
+    module = LoadLibraryExW(name_w, NULL, LOAD_FLAGS);
+#undef LOAD_FLAGS
 #endif
+    av_free(name_w);
+    return module;
 }
 #define dlopen(name, flags) win32_dlopen(name)
 #define dlclose FreeLibrary
diff --git a/libavcodec/mf_utils.h b/libavcodec/mf_utils.h
index 3b12344f3e..aebfb9ad21 100644
--- a/libavcodec/mf_utils.h
+++ b/libavcodec/mf_utils.h
@@ -29,6 +29,7 @@
 // mf*.h headers below indirectly include strmif.h.)
 #include <icodecapi.h>
 #else
+#define NO_DSHOW_STRSAFE
 #include <dshow.h>
 // Older versions of mingw-w64 need codecapi.h explicitly included, while newer
 // ones include it implicitly from dshow.h (via uuids.h).
-- 
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply	[flat|nested] 7+ messages in thread
- * [FFmpeg-devel] [PATCH v20 3/5] fftools: Remove MAX_PATH limit and switch to UTF-8 versions of fopen() and getenv()
  2022-06-20 10:29 [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup() Nil Admirari
  2022-06-20 10:29 ` [FFmpeg-devel] [PATCH v20 2/5] compat/w32dlfcn.h: Remove MAX_PATH limit and replace LoadLibraryExA with LoadLibraryExW Nil Admirari
@ 2022-06-20 10:29 ` Nil Admirari
  2022-06-20 10:30 ` [FFmpeg-devel] [PATCH v20 4/5] libavformat: Remove MAX_PATH limit and use UTF-8 version of getenv() Nil Admirari
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Nil Admirari @ 2022-06-20 10:29 UTC (permalink / raw)
  To: ffmpeg-devel
---
 fftools/cmdutils.c   | 53 +++++++++++++++++++++++++++++++++-----------
 fftools/ffmpeg_opt.c |  9 ++++++--
 2 files changed, 47 insertions(+), 15 deletions(-)
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index 5d7cdc3e10..69a6f54ea3 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -39,6 +39,7 @@
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/display.h"
+#include "libavutil/getenv_utf8.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/libm.h"
@@ -47,9 +48,11 @@
 #include "libavutil/dict.h"
 #include "libavutil/opt.h"
 #include "cmdutils.h"
+#include "fopen_utf8.h"
 #include "opt_common.h"
 #ifdef _WIN32
 #include <windows.h>
+#include "compat/w32dlfcn.h"
 #endif
 
 AVDictionary *sws_dict;
@@ -465,7 +468,7 @@ static void check_options(const OptionDef *po)
 void parse_loglevel(int argc, char **argv, const OptionDef *options)
 {
     int idx = locate_option(argc, argv, options, "loglevel");
-    const char *env;
+    char *env;
 
     check_options(options);
 
@@ -474,7 +477,8 @@ void parse_loglevel(int argc, char **argv, const OptionDef *options)
     if (idx && argv[idx + 1])
         opt_loglevel(NULL, "loglevel", argv[idx + 1]);
     idx = locate_option(argc, argv, options, "report");
-    if ((env = getenv("FFREPORT")) || idx) {
+    env = getenv_utf8("FFREPORT");
+    if (env || idx) {
         FILE *report_file = NULL;
         init_report(env, &report_file);
         if (report_file) {
@@ -487,6 +491,7 @@ void parse_loglevel(int argc, char **argv, const OptionDef *options)
             fflush(report_file);
         }
     }
+    freeenv_utf8(env);
     idx = locate_option(argc, argv, options, "hide_banner");
     if (idx)
         hide_banner = 1;
@@ -812,28 +817,45 @@ FILE *get_preset_file(char *filename, size_t filename_size,
 {
     FILE *f = NULL;
     int i;
-    const char *base[3] = { getenv("FFMPEG_DATADIR"),
-                            getenv("HOME"),
+#if HAVE_GETMODULEHANDLE && defined(_WIN32)
+    char *datadir = NULL;
+#endif
+    char *env_home = getenv_utf8("HOME");
+    char *env_ffmpeg_datadir = getenv_utf8("FFMPEG_DATADIR");
+    const char *base[3] = { env_home,
+                            env_ffmpeg_datadir,
                             FFMPEG_DATADIR, };
 
     if (is_path) {
         av_strlcpy(filename, preset_name, filename_size);
-        f = fopen(filename, "r");
+        f = fopen_utf8(filename, "r");
     } else {
 #if HAVE_GETMODULEHANDLE && defined(_WIN32)
-        char datadir[MAX_PATH], *ls;
+        wchar_t *datadir_w = get_module_filename(NULL);
         base[2] = NULL;
 
-        if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
+        if (wchartoutf8(datadir_w, &datadir))
+            datadir = NULL;
+        av_free(datadir_w);
+
+        if (datadir)
         {
-            for (ls = datadir; ls < datadir + strlen(datadir); ls++)
+            char *ls;
+            for (ls = datadir; *ls; ls++)
                 if (*ls == '\\') *ls = '/';
 
             if (ls = strrchr(datadir, '/'))
             {
-                *ls = 0;
-                strncat(datadir, "/ffpresets",  sizeof(datadir) - 1 - strlen(datadir));
-                base[2] = datadir;
+                ptrdiff_t datadir_len = ls - datadir;
+                size_t desired_size = datadir_len + strlen("/ffpresets") + 1;
+                char *new_datadir = av_realloc_array(
+                    datadir, desired_size, sizeof *datadir);
+                if (new_datadir) {
+                    datadir = new_datadir;
+                    datadir[datadir_len] = 0;
+                    strncat(datadir, "/ffpresets",  desired_size - 1 - datadir_len);
+                    base[2] = datadir;
+                }
             }
         }
 #endif
@@ -842,17 +864,22 @@ FILE *get_preset_file(char *filename, size_t filename_size,
                 continue;
             snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
                      i != 1 ? "" : "/.ffmpeg", preset_name);
-            f = fopen(filename, "r");
+            f = fopen_utf8(filename, "r");
             if (!f && codec_name) {
                 snprintf(filename, filename_size,
                          "%s%s/%s-%s.ffpreset",
                          base[i], i != 1 ? "" : "/.ffmpeg", codec_name,
                          preset_name);
-                f = fopen(filename, "r");
+                f = fopen_utf8(filename, "r");
             }
         }
     }
 
+#if HAVE_GETMODULEHANDLE && defined(_WIN32)
+    av_free(datadir);
+#endif
+    freeenv_utf8(env_ffmpeg_datadir);
+    freeenv_utf8(env_home);
     return f;
 }
 
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 398067da96..e08455478f 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -44,6 +44,7 @@
 #include "libavutil/avutil.h"
 #include "libavutil/bprint.h"
 #include "libavutil/channel_layout.h"
+#include "libavutil/getenv_utf8.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/fifo.h"
 #include "libavutil/mathematics.h"
@@ -1402,8 +1403,10 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV
 {
     int i, ret = -1;
     char filename[1000];
-    const char *base[3] = { getenv("AVCONV_DATADIR"),
-                            getenv("HOME"),
+    char *env_avconv_datadir = getenv_utf8("AVCONV_DATADIR");
+    char *env_home = getenv_utf8("HOME");
+    const char *base[3] = { env_avconv_datadir,
+                            env_home,
                             AVCONV_DATADIR,
                             };
 
@@ -1421,6 +1424,8 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV
             ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
         }
     }
+    freeenv_utf8(env_home);
+    freeenv_utf8(env_avconv_datadir);
     return ret;
 }
 
-- 
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply	[flat|nested] 7+ messages in thread
- * [FFmpeg-devel] [PATCH v20 4/5] libavformat: Remove MAX_PATH limit and use UTF-8 version of getenv()
  2022-06-20 10:29 [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup() Nil Admirari
  2022-06-20 10:29 ` [FFmpeg-devel] [PATCH v20 2/5] compat/w32dlfcn.h: Remove MAX_PATH limit and replace LoadLibraryExA with LoadLibraryExW Nil Admirari
  2022-06-20 10:29 ` [FFmpeg-devel] [PATCH v20 3/5] fftools: Remove MAX_PATH limit and switch to UTF-8 versions of fopen() and getenv() Nil Admirari
@ 2022-06-20 10:30 ` Nil Admirari
  2022-06-20 10:30 ` [FFmpeg-devel] [PATCH v20 5/5] libavfilter/vf_frei0r.c: Use " Nil Admirari
  2022-06-20 19:05 ` [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup() Martin Storsjö
  4 siblings, 0 replies; 7+ messages in thread
From: Nil Admirari @ 2022-06-20 10:30 UTC (permalink / raw)
  To: ffmpeg-devel
1. getenv() is replaced with getenv_utf8() across libavformat.
2. New versions of AviSynth+ are now called with UTF-8 filenames.
3. Old versions of AviSynth are still using ANSI strings,
   but MAX_PATH limit on filename is removed.
---
 libavformat/avisynth.c    | 39 +++++++++++++++++++++++++++------------
 libavformat/http.c        | 22 ++++++++++++++--------
 libavformat/ipfsgateway.c | 36 ++++++++++++++++++++++++------------
 libavformat/tls.c         | 11 +++++++++--
 4 files changed, 74 insertions(+), 34 deletions(-)
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index 8ba2bdead2..a97d12b6b6 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -34,6 +34,7 @@
 /* Platform-specific directives. */
 #ifdef _WIN32
   #include "compat/w32dlfcn.h"
+  #include "libavutil/wchar_filename.h"
   #undef EXTERN_C
   #define AVISYNTH_LIB "avisynth"
 #else
@@ -56,6 +57,7 @@ typedef struct AviSynthLibrary {
 #define AVSC_DECLARE_FUNC(name) name ## _func name
     AVSC_DECLARE_FUNC(avs_bit_blt);
     AVSC_DECLARE_FUNC(avs_clip_get_error);
+    AVSC_DECLARE_FUNC(avs_check_version);
     AVSC_DECLARE_FUNC(avs_create_script_environment);
     AVSC_DECLARE_FUNC(avs_delete_script_environment);
     AVSC_DECLARE_FUNC(avs_get_audio);
@@ -137,6 +139,7 @@ static av_cold int avisynth_load_library(void)
 
     LOAD_AVS_FUNC(avs_bit_blt, 0);
     LOAD_AVS_FUNC(avs_clip_get_error, 0);
+    LOAD_AVS_FUNC(avs_check_version, 0);
     LOAD_AVS_FUNC(avs_create_script_environment, 0);
     LOAD_AVS_FUNC(avs_delete_script_environment, 0);
     LOAD_AVS_FUNC(avs_get_audio, 0);
@@ -807,26 +810,38 @@ static int avisynth_create_stream(AVFormatContext *s)
 static int avisynth_open_file(AVFormatContext *s)
 {
     AviSynthContext *avs = s->priv_data;
-    AVS_Value arg, val;
+    AVS_Value val;
     int ret;
-#ifdef _WIN32
-    char filename_ansi[MAX_PATH * 4];
-    wchar_t filename_wc[MAX_PATH * 4];
-#endif
 
     if (ret = avisynth_context_create(s))
         return ret;
 
+    if (!avs_library.avs_check_version(avs->env, 7)) {
+        AVS_Value args[] = {
+            avs_new_value_string(s->url),
+            avs_new_value_bool(1) // filename is in UTF-8
+        };
+        val = avs_library.avs_invoke(avs->env, "Import",
+                                     avs_new_value_array(args, 2), 0);
+    } else {
+        AVS_Value arg;
 #ifdef _WIN32
-    /* Convert UTF-8 to ANSI code page */
-    MultiByteToWideChar(CP_UTF8, 0, s->url, -1, filename_wc, MAX_PATH * 4);
-    WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi,
-                        MAX_PATH * 4, NULL, NULL);
-    arg = avs_new_value_string(filename_ansi);
+        char *filename_ansi;
+        /* Convert UTF-8 to ANSI code page */
+        if (utf8toansi(s->url, &filename_ansi)) {
+            ret = AVERROR_UNKNOWN;
+            goto fail;
+        }
+        arg = avs_new_value_string(filename_ansi);
 #else
-    arg = avs_new_value_string(s->url);
+        arg = avs_new_value_string(s->url);
 #endif
-    val = avs_library.avs_invoke(avs->env, "Import", arg, 0);
+        val = avs_library.avs_invoke(avs->env, "Import", arg, 0);
+#ifdef _WIN32
+        av_free(filename_ansi);
+#endif
+    }
+
     if (avs_is_error(val)) {
         av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val));
         ret = AVERROR_UNKNOWN;
diff --git a/libavformat/http.c b/libavformat/http.c
index c8f3f4b6a3..f80ea7bf35 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -29,6 +29,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/bprint.h"
+#include "libavutil/getenv_utf8.h"
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
 #include "libavutil/parseutils.h"
@@ -198,12 +199,13 @@ void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
 static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
 {
     const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
+    char *env_http_proxy, *env_no_proxy;
     char *hashmark;
     char hostname[1024], hoststr[1024], proto[10];
     char auth[1024], proxyauth[1024] = "";
     char path1[MAX_URL_SIZE], sanitized_path[MAX_URL_SIZE + 1];
     char buf[1024], urlbuf[MAX_URL_SIZE];
-    int port, use_proxy, err;
+    int port, use_proxy, err = 0;
     HTTPContext *s = h->priv_data;
 
     av_url_split(proto, sizeof(proto), auth, sizeof(auth),
@@ -211,9 +213,13 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
                  path1, sizeof(path1), s->location);
     ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
 
-    proxy_path = s->http_proxy ? s->http_proxy : getenv("http_proxy");
-    use_proxy  = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) &&
+    env_http_proxy = getenv_utf8("http_proxy");
+    proxy_path = s->http_proxy ? s->http_proxy : env_http_proxy;
+
+    env_no_proxy = getenv_utf8("no_proxy");
+    use_proxy  = !ff_http_match_no_proxy(env_no_proxy, hostname) &&
                  proxy_path && av_strstart(proxy_path, "http://", NULL);
+    freeenv_utf8(env_no_proxy);
 
     if (!strcmp(proto, "https")) {
         lower_proto = "tls";
@@ -224,7 +230,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
         if (s->http_proxy) {
             err = av_dict_set(options, "http_proxy", s->http_proxy, 0);
             if (err < 0)
-                return err;
+                goto end;
         }
     }
     if (port < 0)
@@ -259,12 +265,12 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
         err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE,
                                    &h->interrupt_callback, options,
                                    h->protocol_whitelist, h->protocol_blacklist, h);
-        if (err < 0)
-            return err;
     }
 
-    return http_connect(h, path, local_path, hoststr,
-                        auth, proxyauth);
+end:
+    freeenv_utf8(env_http_proxy);
+    return err < 0 ? err : http_connect(
+        h, path, local_path, hoststr, auth, proxyauth);
 }
 
 static int http_should_reconnect(HTTPContext *s, int err)
diff --git a/libavformat/ipfsgateway.c b/libavformat/ipfsgateway.c
index 83d52293b4..5a5178c563 100644
--- a/libavformat/ipfsgateway.c
+++ b/libavformat/ipfsgateway.c
@@ -20,6 +20,7 @@
  */
 
 #include "libavutil/avstring.h"
+#include "libavutil/getenv_utf8.h"
 #include "libavutil/opt.h"
 #include <sys/stat.h>
 #include "os_support.h"
@@ -55,12 +56,15 @@ static int populate_ipfs_gateway(URLContext *h)
     int stat_ret = 0;
     int ret = AVERROR(EINVAL);
     FILE *gateway_file = NULL;
+    char *env_ipfs_gateway, *env_ipfs_path;
 
     // Test $IPFS_GATEWAY.
-    if (getenv("IPFS_GATEWAY") != NULL) {
-        if (snprintf(c->gateway_buffer, sizeof(c->gateway_buffer), "%s",
-                     getenv("IPFS_GATEWAY"))
-            >= sizeof(c->gateway_buffer)) {
+    env_ipfs_gateway = getenv_utf8("IPFS_GATEWAY");
+    if (env_ipfs_gateway != NULL) {
+        int printed = snprintf(c->gateway_buffer, sizeof(c->gateway_buffer),
+                               "%s", env_ipfs_gateway);
+        freeenv_utf8(env_ipfs_gateway);
+        if (printed >= sizeof(c->gateway_buffer)) {
             av_log(h, AV_LOG_WARNING,
                    "The IPFS_GATEWAY environment variable "
                    "exceeds the maximum length. "
@@ -77,20 +81,26 @@ static int populate_ipfs_gateway(URLContext *h)
 
     // We need to know the IPFS folder to - eventually - read the contents of
     // the "gateway" file which would tell us the gateway to use.
-    if (getenv("IPFS_PATH") == NULL) {
+    env_ipfs_path = getenv_utf8("IPFS_PATH");
+    if (env_ipfs_path == NULL) {
+        int printed;
+        char *env_home = getenv_utf8("HOME");
+
         av_log(h, AV_LOG_DEBUG, "$IPFS_PATH is empty.\n");
 
         // Try via the home folder.
-        if (getenv("HOME") == NULL) {
+        if (env_home == NULL) {
             av_log(h, AV_LOG_WARNING, "$HOME appears to be empty.\n");
             ret = AVERROR(EINVAL);
             goto err;
         }
 
         // Verify the composed path fits.
-        if (snprintf(ipfs_full_data_folder, sizeof(ipfs_full_data_folder),
-                     "%s/.ipfs/", getenv("HOME"))
-            >= sizeof(ipfs_full_data_folder)) {
+        printed = snprintf(
+            ipfs_full_data_folder, sizeof(ipfs_full_data_folder),
+            "%s/.ipfs/", env_home);
+        freeenv_utf8(env_home);
+        if (printed >= sizeof(ipfs_full_data_folder)) {
             av_log(h, AV_LOG_WARNING,
                    "The IPFS data path exceeds the "
                    "max path length (%zu)\n",
@@ -113,9 +123,11 @@ static int populate_ipfs_gateway(URLContext *h)
             goto err;
         }
     } else {
-        if (snprintf(ipfs_full_data_folder, sizeof(ipfs_full_data_folder), "%s",
-                     getenv("IPFS_PATH"))
-            >= sizeof(ipfs_full_data_folder)) {
+        int printed = snprintf(
+            ipfs_full_data_folder, sizeof(ipfs_full_data_folder),
+            "%s", env_ipfs_path);
+        freeenv_utf8(env_ipfs_path);
+        if (printed >= sizeof(ipfs_full_data_folder)) {
             av_log(h, AV_LOG_WARNING,
                    "The IPFS_PATH environment variable "
                    "exceeds the maximum length. "
diff --git a/libavformat/tls.c b/libavformat/tls.c
index 302c0f8d59..e42d399862 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -26,6 +26,7 @@
 #include "url.h"
 #include "tls.h"
 #include "libavutil/avstring.h"
+#include "libavutil/getenv_utf8.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 
@@ -60,6 +61,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
     char buf[200], opts[50] = "";
     struct addrinfo hints = { 0 }, *ai = NULL;
     const char *proxy_path;
+    char *env_http_proxy, *env_no_proxy;
     int use_proxy;
 
     set_options(c, uri);
@@ -89,9 +91,13 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
     if (!c->host && !(c->host = av_strdup(c->underlying_host)))
         return AVERROR(ENOMEM);
 
-    proxy_path = c->http_proxy ? c->http_proxy : getenv("http_proxy");
-    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), c->underlying_host) &&
+    env_http_proxy = getenv_utf8("http_proxy");
+    proxy_path = c->http_proxy ? c->http_proxy : env_http_proxy;
+
+    env_no_proxy = getenv_utf8("no_proxy");
+    use_proxy = !ff_http_match_no_proxy(env_no_proxy, c->underlying_host) &&
                 proxy_path && av_strstart(proxy_path, "http://", NULL);
+    freeenv_utf8(env_no_proxy);
 
     if (use_proxy) {
         char proxy_host[200], proxy_auth[200], dest[200];
@@ -104,6 +110,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV
                     proxy_port, "/%s", dest);
     }
 
+    freeenv_utf8(env_http_proxy);
     return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE,
                                 &parent->interrupt_callback, options,
                                 parent->protocol_whitelist, parent->protocol_blacklist, parent);
-- 
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply	[flat|nested] 7+ messages in thread
- * [FFmpeg-devel] [PATCH v20 5/5] libavfilter/vf_frei0r.c: Use UTF-8 version of getenv()
  2022-06-20 10:29 [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup() Nil Admirari
                   ` (2 preceding siblings ...)
  2022-06-20 10:30 ` [FFmpeg-devel] [PATCH v20 4/5] libavformat: Remove MAX_PATH limit and use UTF-8 version of getenv() Nil Admirari
@ 2022-06-20 10:30 ` Nil Admirari
  2022-06-20 19:05 ` [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup() Martin Storsjö
  4 siblings, 0 replies; 7+ messages in thread
From: Nil Admirari @ 2022-06-20 10:30 UTC (permalink / raw)
  To: ffmpeg-devel
---
 libavfilter/vf_frei0r.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index f11ae6e55c..1e01114b76 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -31,6 +31,7 @@
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
+#include "libavutil/getenv_utf8.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
 #include "libavutil/mathematics.h"
@@ -204,7 +205,7 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
     }
 
     /* see: http://frei0r.dyne.org/codedoc/html/group__pluglocations.html */
-    if ((path = av_strdup(getenv("FREI0R_PATH")))) {
+    if (path = getenv_dup("FREI0R_PATH")) {
 #ifdef _WIN32
         const char *separator = ";";
 #else
@@ -231,12 +232,17 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
         if (ret < 0)
             return ret;
     }
-    if (!s->dl_handle && (path = getenv("HOME"))) {
+    if (!s->dl_handle && (path = getenv_utf8("HOME"))) {
         char *prefix = av_asprintf("%s/.frei0r-1/lib/", path);
-        if (!prefix)
-            return AVERROR(ENOMEM);
+        if (!prefix) {
+            ret = AVERROR(ENOMEM);
+            goto home_path_end;
+        }
         ret = load_path(ctx, &s->dl_handle, prefix, dl_name);
         av_free(prefix);
+
+    home_path_end:
+        freeenv_utf8(path);
         if (ret < 0)
             return ret;
     }
-- 
2.34.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply	[flat|nested] 7+ messages in thread
- * Re: [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup()
  2022-06-20 10:29 [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup() Nil Admirari
                   ` (3 preceding siblings ...)
  2022-06-20 10:30 ` [FFmpeg-devel] [PATCH v20 5/5] libavfilter/vf_frei0r.c: Use " Nil Admirari
@ 2022-06-20 19:05 ` Martin Storsjö
  2022-06-21 10:33   ` Martin Storsjö
  4 siblings, 1 reply; 7+ messages in thread
From: Martin Storsjö @ 2022-06-20 19:05 UTC (permalink / raw)
  To: FFmpeg development discussions and patches
On Mon, 20 Jun 2022, Nil Admirari wrote:
> wchartoutf8() converts strings returned by WinAPI into UTF-8,
> which is FFmpeg's preffered encoding.
>
> Some external dependencies, such as AviSynth, are still
> not Unicode-enabled. utf8toansi() converts UTF-8 strings
> into ANSI in two steps: UTF-8 -> wchar_t -> ANSI.
> wchartoansi() is responsible for the second step of the conversion.
> Conversion in just one step is not supported by WinAPI.
>
> Since these character converting functions allocate the buffer
> of necessary size, they also facilitate the removal of MAX_PATH limit
> in places where fixed-size ANSI/WCHAR strings were used
> as filename buffers.
>
> On Windows, getenv_utf8() wraps _wgetenv() converting its input from
> and its output to UTF-8. Strings returned by getenv_utf8()
> must be freed by freeenv_utf8().
>
> On all other platforms getenv_utf8() is a wrapper around getenv(),
> and freeenv_utf8() is a no-op.
>
> The value returned by plain getenv() cannot be modified;
> av_strdup() is usually used when modifications are required.
> However, on Windows, av_strdup() after getenv_utf8() leads to
> unnecessary allocation. getenv_dup() is introduced to avoid
> such an allocation. Value returned by getenv_dup() must be freed
> by av_free().
>
> Because of cleanup complexities, in places that only test the existence
> of an environment variable or compare its value with a string
> consisting entirely of ASCII characters, the use of plain getenv()
> is still preferred. (libavutil/log.c check_color_terminal()
> is an example of such a place.)
>
> Plain getenv() is also preffered in UNIX-only code,
> such as bktr.c, fbdev_common.c, oss.c in libavdevice
> or af_ladspa.c in libavfilter.
> ---
> configure                  |  1 +
> libavutil/getenv_utf8.h    | 86 ++++++++++++++++++++++++++++++++++++++
> libavutil/wchar_filename.h | 53 +++++++++++++++++++++++
> 3 files changed, 140 insertions(+)
> create mode 100644 libavutil/getenv_utf8.h
This set looks good to me, thanks! Will push tomorrow if there's nothing 
more to add on it.
// Martin
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply	[flat|nested] 7+ messages in thread
- * Re: [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup()
  2022-06-20 19:05 ` [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup() Martin Storsjö
@ 2022-06-21 10:33   ` Martin Storsjö
  0 siblings, 0 replies; 7+ messages in thread
From: Martin Storsjö @ 2022-06-21 10:33 UTC (permalink / raw)
  To: FFmpeg development discussions and patches
On Mon, 20 Jun 2022, Martin Storsjö wrote:
> On Mon, 20 Jun 2022, Nil Admirari wrote:
>
>> wchartoutf8() converts strings returned by WinAPI into UTF-8,
>> which is FFmpeg's preffered encoding.
>> 
>> Some external dependencies, such as AviSynth, are still
>> not Unicode-enabled. utf8toansi() converts UTF-8 strings
>> into ANSI in two steps: UTF-8 -> wchar_t -> ANSI.
>> wchartoansi() is responsible for the second step of the conversion.
>> Conversion in just one step is not supported by WinAPI.
>> 
>> Since these character converting functions allocate the buffer
>> of necessary size, they also facilitate the removal of MAX_PATH limit
>> in places where fixed-size ANSI/WCHAR strings were used
>> as filename buffers.
>> 
>> On Windows, getenv_utf8() wraps _wgetenv() converting its input from
>> and its output to UTF-8. Strings returned by getenv_utf8()
>> must be freed by freeenv_utf8().
>> 
>> On all other platforms getenv_utf8() is a wrapper around getenv(),
>> and freeenv_utf8() is a no-op.
>> 
>> The value returned by plain getenv() cannot be modified;
>> av_strdup() is usually used when modifications are required.
>> However, on Windows, av_strdup() after getenv_utf8() leads to
>> unnecessary allocation. getenv_dup() is introduced to avoid
>> such an allocation. Value returned by getenv_dup() must be freed
>> by av_free().
>> 
>> Because of cleanup complexities, in places that only test the existence
>> of an environment variable or compare its value with a string
>> consisting entirely of ASCII characters, the use of plain getenv()
>> is still preferred. (libavutil/log.c check_color_terminal()
>> is an example of such a place.)
>> 
>> Plain getenv() is also preffered in UNIX-only code,
>> such as bktr.c, fbdev_common.c, oss.c in libavdevice
>> or af_ladspa.c in libavfilter.
>> ---
>> configure                  |  1 +
>> libavutil/getenv_utf8.h    | 86 ++++++++++++++++++++++++++++++++++++++
>> libavutil/wchar_filename.h | 53 +++++++++++++++++++++++
>> 3 files changed, 140 insertions(+)
>> create mode 100644 libavutil/getenv_utf8.h
>
> This set looks good to me, thanks! Will push tomorrow if there's nothing more 
> to add on it.
Pushed now, thanks!
// Martin
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply	[flat|nested] 7+ messages in thread