1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-01-24 13:56:33 +02:00

libavformat: Remove MAX_PATH limit and use UTF-8 version of getenv()

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.

Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
Nil Admirari 2022-06-20 13:30:00 +03:00 committed by Martin Storsjö
parent 13350e81fd
commit c381f5412f
4 changed files with 74 additions and 34 deletions

View File

@ -34,6 +34,7 @@
/* Platform-specific directives. */ /* Platform-specific directives. */
#ifdef _WIN32 #ifdef _WIN32
#include "compat/w32dlfcn.h" #include "compat/w32dlfcn.h"
#include "libavutil/wchar_filename.h"
#undef EXTERN_C #undef EXTERN_C
#define AVISYNTH_LIB "avisynth" #define AVISYNTH_LIB "avisynth"
#else #else
@ -56,6 +57,7 @@ typedef struct AviSynthLibrary {
#define AVSC_DECLARE_FUNC(name) name ## _func name #define AVSC_DECLARE_FUNC(name) name ## _func name
AVSC_DECLARE_FUNC(avs_bit_blt); AVSC_DECLARE_FUNC(avs_bit_blt);
AVSC_DECLARE_FUNC(avs_clip_get_error); AVSC_DECLARE_FUNC(avs_clip_get_error);
AVSC_DECLARE_FUNC(avs_check_version);
AVSC_DECLARE_FUNC(avs_create_script_environment); AVSC_DECLARE_FUNC(avs_create_script_environment);
AVSC_DECLARE_FUNC(avs_delete_script_environment); AVSC_DECLARE_FUNC(avs_delete_script_environment);
AVSC_DECLARE_FUNC(avs_get_audio); 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_bit_blt, 0);
LOAD_AVS_FUNC(avs_clip_get_error, 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_create_script_environment, 0);
LOAD_AVS_FUNC(avs_delete_script_environment, 0); LOAD_AVS_FUNC(avs_delete_script_environment, 0);
LOAD_AVS_FUNC(avs_get_audio, 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) static int avisynth_open_file(AVFormatContext *s)
{ {
AviSynthContext *avs = s->priv_data; AviSynthContext *avs = s->priv_data;
AVS_Value arg, val; AVS_Value val;
int ret; int ret;
#ifdef _WIN32
char filename_ansi[MAX_PATH * 4];
wchar_t filename_wc[MAX_PATH * 4];
#endif
if (ret = avisynth_context_create(s)) if (ret = avisynth_context_create(s))
return ret; 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 #ifdef _WIN32
/* Convert UTF-8 to ANSI code page */ char *filename_ansi;
MultiByteToWideChar(CP_UTF8, 0, s->url, -1, filename_wc, MAX_PATH * 4); /* Convert UTF-8 to ANSI code page */
WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi, if (utf8toansi(s->url, &filename_ansi)) {
MAX_PATH * 4, NULL, NULL); ret = AVERROR_UNKNOWN;
arg = avs_new_value_string(filename_ansi); goto fail;
}
arg = avs_new_value_string(filename_ansi);
#else #else
arg = avs_new_value_string(s->url); arg = avs_new_value_string(s->url);
#endif #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)) { if (avs_is_error(val)) {
av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val)); av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val));
ret = AVERROR_UNKNOWN; ret = AVERROR_UNKNOWN;

View File

@ -29,6 +29,7 @@
#include "libavutil/avassert.h" #include "libavutil/avassert.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/bprint.h" #include "libavutil/bprint.h"
#include "libavutil/getenv_utf8.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/time.h" #include "libavutil/time.h"
#include "libavutil/parseutils.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) static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
{ {
const char *path, *proxy_path, *lower_proto = "tcp", *local_path; const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
char *env_http_proxy, *env_no_proxy;
char *hashmark; char *hashmark;
char hostname[1024], hoststr[1024], proto[10]; char hostname[1024], hoststr[1024], proto[10];
char auth[1024], proxyauth[1024] = ""; char auth[1024], proxyauth[1024] = "";
char path1[MAX_URL_SIZE], sanitized_path[MAX_URL_SIZE + 1]; char path1[MAX_URL_SIZE], sanitized_path[MAX_URL_SIZE + 1];
char buf[1024], urlbuf[MAX_URL_SIZE]; char buf[1024], urlbuf[MAX_URL_SIZE];
int port, use_proxy, err; int port, use_proxy, err = 0;
HTTPContext *s = h->priv_data; HTTPContext *s = h->priv_data;
av_url_split(proto, sizeof(proto), auth, sizeof(auth), 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); path1, sizeof(path1), s->location);
ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
proxy_path = s->http_proxy ? s->http_proxy : getenv("http_proxy"); env_http_proxy = getenv_utf8("http_proxy");
use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) && 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); proxy_path && av_strstart(proxy_path, "http://", NULL);
freeenv_utf8(env_no_proxy);
if (!strcmp(proto, "https")) { if (!strcmp(proto, "https")) {
lower_proto = "tls"; lower_proto = "tls";
@ -224,7 +230,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
if (s->http_proxy) { if (s->http_proxy) {
err = av_dict_set(options, "http_proxy", s->http_proxy, 0); err = av_dict_set(options, "http_proxy", s->http_proxy, 0);
if (err < 0) if (err < 0)
return err; goto end;
} }
} }
if (port < 0) 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, err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE,
&h->interrupt_callback, options, &h->interrupt_callback, options,
h->protocol_whitelist, h->protocol_blacklist, h); h->protocol_whitelist, h->protocol_blacklist, h);
if (err < 0)
return err;
} }
return http_connect(h, path, local_path, hoststr, end:
auth, proxyauth); 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) static int http_should_reconnect(HTTPContext *s, int err)

View File

@ -20,6 +20,7 @@
*/ */
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/getenv_utf8.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include <sys/stat.h> #include <sys/stat.h>
#include "os_support.h" #include "os_support.h"
@ -55,12 +56,15 @@ static int populate_ipfs_gateway(URLContext *h)
int stat_ret = 0; int stat_ret = 0;
int ret = AVERROR(EINVAL); int ret = AVERROR(EINVAL);
FILE *gateway_file = NULL; FILE *gateway_file = NULL;
char *env_ipfs_gateway, *env_ipfs_path;
// Test $IPFS_GATEWAY. // Test $IPFS_GATEWAY.
if (getenv("IPFS_GATEWAY") != NULL) { env_ipfs_gateway = getenv_utf8("IPFS_GATEWAY");
if (snprintf(c->gateway_buffer, sizeof(c->gateway_buffer), "%s", if (env_ipfs_gateway != NULL) {
getenv("IPFS_GATEWAY")) int printed = snprintf(c->gateway_buffer, sizeof(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, av_log(h, AV_LOG_WARNING,
"The IPFS_GATEWAY environment variable " "The IPFS_GATEWAY environment variable "
"exceeds the maximum length. " "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 // We need to know the IPFS folder to - eventually - read the contents of
// the "gateway" file which would tell us the gateway to use. // 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"); av_log(h, AV_LOG_DEBUG, "$IPFS_PATH is empty.\n");
// Try via the home folder. // 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"); av_log(h, AV_LOG_WARNING, "$HOME appears to be empty.\n");
ret = AVERROR(EINVAL); ret = AVERROR(EINVAL);
goto err; goto err;
} }
// Verify the composed path fits. // Verify the composed path fits.
if (snprintf(ipfs_full_data_folder, sizeof(ipfs_full_data_folder), printed = snprintf(
"%s/.ipfs/", getenv("HOME")) ipfs_full_data_folder, sizeof(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, av_log(h, AV_LOG_WARNING,
"The IPFS data path exceeds the " "The IPFS data path exceeds the "
"max path length (%zu)\n", "max path length (%zu)\n",
@ -113,9 +123,11 @@ static int populate_ipfs_gateway(URLContext *h)
goto err; goto err;
} }
} else { } else {
if (snprintf(ipfs_full_data_folder, sizeof(ipfs_full_data_folder), "%s", int printed = snprintf(
getenv("IPFS_PATH")) ipfs_full_data_folder, sizeof(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, av_log(h, AV_LOG_WARNING,
"The IPFS_PATH environment variable " "The IPFS_PATH environment variable "
"exceeds the maximum length. " "exceeds the maximum length. "

View File

@ -26,6 +26,7 @@
#include "url.h" #include "url.h"
#include "tls.h" #include "tls.h"
#include "libavutil/avstring.h" #include "libavutil/avstring.h"
#include "libavutil/getenv_utf8.h"
#include "libavutil/opt.h" #include "libavutil/opt.h"
#include "libavutil/parseutils.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] = ""; char buf[200], opts[50] = "";
struct addrinfo hints = { 0 }, *ai = NULL; struct addrinfo hints = { 0 }, *ai = NULL;
const char *proxy_path; const char *proxy_path;
char *env_http_proxy, *env_no_proxy;
int use_proxy; int use_proxy;
set_options(c, uri); 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))) if (!c->host && !(c->host = av_strdup(c->underlying_host)))
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
proxy_path = c->http_proxy ? c->http_proxy : getenv("http_proxy"); env_http_proxy = getenv_utf8("http_proxy");
use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), c->underlying_host) && 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); proxy_path && av_strstart(proxy_path, "http://", NULL);
freeenv_utf8(env_no_proxy);
if (use_proxy) { if (use_proxy) {
char proxy_host[200], proxy_auth[200], dest[200]; 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); proxy_port, "/%s", dest);
} }
freeenv_utf8(env_http_proxy);
return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE, return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE,
&parent->interrupt_callback, options, &parent->interrupt_callback, options,
parent->protocol_whitelist, parent->protocol_blacklist, parent); parent->protocol_whitelist, parent->protocol_blacklist, parent);