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.
Unified · Split
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | /* Platform-specific directives. */ | 34 | /* Platform-specific directives. */ |
| 35 | #ifdef _WIN32 | 35 | #ifdef _WIN32 |
| 36 | #include "compat/w32dlfcn.h" | 36 | #include "compat/w32dlfcn.h" |
| 37 | #include "libavutil/wchar_filename.h" | ||
| 37 | #undef EXTERN_C | 38 | #undef EXTERN_C |
| 38 | #define AVISYNTH_LIB "avisynth" | 39 | #define AVISYNTH_LIB "avisynth" |
| 39 | #else | 40 | #else |
| @@ -56,6 +57,7 @@ typedef struct AviSynthLibrary { · 16 unmodified lines | |||
| 56 | #define AVSC_DECLARE_FUNC(name) name ## _func name | 57 | #define AVSC_DECLARE_FUNC(name) name ## _func name |
| 57 | AVSC_DECLARE_FUNC(avs_bit_blt); | 58 | AVSC_DECLARE_FUNC(avs_bit_blt); |
| 58 | AVSC_DECLARE_FUNC(avs_clip_get_error); | 59 | AVSC_DECLARE_FUNC(avs_clip_get_error); |
| 60 | AVSC_DECLARE_FUNC(avs_check_version); | ||
| 59 | AVSC_DECLARE_FUNC(avs_create_script_environment); | 61 | AVSC_DECLARE_FUNC(avs_create_script_environment); |
| 60 | AVSC_DECLARE_FUNC(avs_delete_script_environment); | 62 | AVSC_DECLARE_FUNC(avs_delete_script_environment); |
| 61 | AVSC_DECLARE_FUNC(avs_get_audio); | 63 | AVSC_DECLARE_FUNC(avs_get_audio); |
| @@ -137,6 +139,7 @@ static av_cold int avisynth_load_library(void) · 75 unmodified lines | |||
| 137 | 139 | ||
| 138 | LOAD_AVS_FUNC(avs_bit_blt, 0); | 140 | LOAD_AVS_FUNC(avs_bit_blt, 0); |
| 139 | LOAD_AVS_FUNC(avs_clip_get_error, 0); | 141 | LOAD_AVS_FUNC(avs_clip_get_error, 0); |
| 142 | LOAD_AVS_FUNC(avs_check_version, 0); | ||
| 140 | LOAD_AVS_FUNC(avs_create_script_environment, 0); | 143 | LOAD_AVS_FUNC(avs_create_script_environment, 0); |
| 141 | LOAD_AVS_FUNC(avs_delete_script_environment, 0); | 144 | LOAD_AVS_FUNC(avs_delete_script_environment, 0); |
| 142 | LOAD_AVS_FUNC(avs_get_audio, 0); | 145 | LOAD_AVS_FUNC(avs_get_audio, 0); |
| @@ -807,26 +810,38 @@ static int avisynth_create_stream(AVFormatContext *s) · 664 unmodified lines | |||
| 807 | static int avisynth_open_file(AVFormatContext *s) | 810 | static int avisynth_open_file(AVFormatContext *s) |
| 808 | { | 811 | { |
| 809 | AviSynthContext *avs = s->priv_data; | 812 | AviSynthContext *avs = s->priv_data; |
| 810 | AVS_Value arg, val; | 813 | AVS_Value val; |
| 811 | int ret; | 814 | int ret; |
| 812 | #ifdef _WIN32 | ||
| 813 | char filename_ansi[MAX_PATH * 4]; | ||
| 814 | wchar_t filename_wc[MAX_PATH * 4]; | ||
| 815 | #endif | ||
| 816 | 815 | ||
| 817 | if (ret = avisynth_context_create(s)) | 816 | if (ret = avisynth_context_create(s)) |
| 818 | return ret; | 817 | return ret; |
| 819 | 818 | ||
| 819 | if (!avs_library.avs_check_version(avs->env, 7)) { | ||
| 820 | AVS_Value args[] = { | ||
| 821 | avs_new_value_string(s->url), | ||
| 822 | avs_new_value_bool(1) // filename is in UTF-8 | ||
| 823 | }; | ||
| 824 | val = avs_library.avs_invoke(avs->env, "Import", | ||
| 825 | avs_new_value_array(args, 2), 0); | ||
| 826 | } else { | ||
| 827 | AVS_Value arg; | ||
| 820 | #ifdef _WIN32 | 828 | #ifdef _WIN32 |
| 821 | /* Convert UTF-8 to ANSI code page */ | 829 | char *filename_ansi; |
| 822 | MultiByteToWideChar(CP_UTF8, 0, s->url, -1, filename_wc, MAX_PATH * 4); | 830 | /* Convert UTF-8 to ANSI code page */ |
| 823 | WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi, | 831 | if (utf8toansi(s->url, &filename_ansi)) { |
| 824 | MAX_PATH * 4, NULL, NULL); | 832 | ret = AVERROR_UNKNOWN; |
| 825 | arg = avs_new_value_string(filename_ansi); | 833 | goto fail; |
| 834 | } | ||
| 835 | arg = avs_new_value_string(filename_ansi); | ||
| 826 | #else | 836 | #else |
| 827 | arg = avs_new_value_string(s->url); | 837 | arg = avs_new_value_string(s->url); |
| 828 | #endif | 838 | #endif |
| 829 | val = avs_library.avs_invoke(avs->env, "Import", arg, 0); | 839 | val = avs_library.avs_invoke(avs->env, "Import", arg, 0); |
| 840 | #ifdef _WIN32 | ||
| 841 | av_free(filename_ansi); | ||
| 842 | #endif | ||
| 843 | } | ||
| 844 | |||
| 830 | if (avs_is_error(val)) { | 845 | if (avs_is_error(val)) { |
| 831 | av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val)); | 846 | av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val)); |
| 832 | ret = AVERROR_UNKNOWN; | 847 | ret = AVERROR_UNKNOWN; |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | |||
| 29 | #include "libavutil/avassert.h" | 29 | #include "libavutil/avassert.h" |
| 30 | #include "libavutil/avstring.h" | 30 | #include "libavutil/avstring.h" |
| 31 | #include "libavutil/bprint.h" | 31 | #include "libavutil/bprint.h" |
| 32 | #include "libavutil/getenv_utf8.h" | ||
| 32 | #include "libavutil/opt.h" | 33 | #include "libavutil/opt.h" |
| 33 | #include "libavutil/time.h" | 34 | #include "libavutil/time.h" |
| 34 | #include "libavutil/parseutils.h" | 35 | #include "libavutil/parseutils.h" |
| @@ -198,12 +199,13 @@ void ff_http_init_auth_state(URLContext *dest, const URLContext *src) · 163 unmodified lines | |||
| 198 | static int http_open_cnx_internal(URLContext *h, AVDictionary **options) | 199 | static int http_open_cnx_internal(URLContext *h, AVDictionary **options) |
| 199 | { | 200 | { |
| 200 | const char *path, *proxy_path, *lower_proto = "tcp", *local_path; | 201 | const char *path, *proxy_path, *lower_proto = "tcp", *local_path; |
| 202 | char *env_http_proxy, *env_no_proxy; | ||
| 201 | char *hashmark; | 203 | char *hashmark; |
| 202 | char hostname[1024], hoststr[1024], proto[10]; | 204 | char hostname[1024], hoststr[1024], proto[10]; |
| 203 | char auth[1024], proxyauth[1024] = ""; | 205 | char auth[1024], proxyauth[1024] = ""; |
| 204 | char path1[MAX_URL_SIZE], sanitized_path[MAX_URL_SIZE + 1]; | 206 | char path1[MAX_URL_SIZE], sanitized_path[MAX_URL_SIZE + 1]; |
| 205 | char buf[1024], urlbuf[MAX_URL_SIZE]; | 207 | char buf[1024], urlbuf[MAX_URL_SIZE]; |
| 206 | int port, use_proxy, err; | 208 | int port, use_proxy, err = 0; |
| 207 | HTTPContext *s = h->priv_data; | 209 | HTTPContext *s = h->priv_data; |
| 208 | 210 | ||
| 209 | av_url_split(proto, sizeof(proto), auth, sizeof(auth), | 211 | av_url_split(proto, sizeof(proto), auth, sizeof(auth), |
| @@ -211,9 +213,13 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) · 1 unmodified line | |||
| 211 | path1, sizeof(path1), s->location); | 213 | path1, sizeof(path1), s->location); |
| 212 | ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); | 214 | ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); |
| 213 | 215 | ||
| 214 | proxy_path = s->http_proxy ? s->http_proxy : getenv("http_proxy"); | 216 | env_http_proxy = getenv_utf8("http_proxy"); |
| 215 | use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) && | 217 | proxy_path = s->http_proxy ? s->http_proxy : env_http_proxy; |
| 218 | |||
| 219 | env_no_proxy = getenv_utf8("no_proxy"); | ||
| 220 | use_proxy = !ff_http_match_no_proxy(env_no_proxy, hostname) && | ||
| 216 | proxy_path && av_strstart(proxy_path, "http://", NULL); | 221 | proxy_path && av_strstart(proxy_path, "http://", NULL); |
| 222 | freeenv_utf8(env_no_proxy); | ||
| 217 | 223 | ||
| 218 | if (!strcmp(proto, "https")) { | 224 | if (!strcmp(proto, "https")) { |
| 219 | lower_proto = "tls"; | 225 | lower_proto = "tls"; |
| @@ -224,7 +230,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) · 4 unmodified lines | |||
| 224 | if (s->http_proxy) { | 230 | if (s->http_proxy) { |
| 225 | err = av_dict_set(options, "http_proxy", s->http_proxy, 0); | 231 | err = av_dict_set(options, "http_proxy", s->http_proxy, 0); |
| 226 | if (err < 0) | 232 | if (err < 0) |
| 227 | return err; | 233 | goto end; |
| 228 | } | 234 | } |
| 229 | } | 235 | } |
| 230 | if (port < 0) | 236 | if (port < 0) |
| @@ -259,12 +265,12 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) · 28 unmodified lines | |||
| 259 | err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, | 265 | err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, |
| 260 | &h->interrupt_callback, options, | 266 | &h->interrupt_callback, options, |
| 261 | h->protocol_whitelist, h->protocol_blacklist, h); | 267 | h->protocol_whitelist, h->protocol_blacklist, h); |
| 262 | if (err < 0) | ||
| 263 | return err; | ||
| 264 | } | 268 | } |
| 265 | 269 | ||
| 266 | return http_connect(h, path, local_path, hoststr, | 270 | end: |
| 267 | auth, proxyauth); | 271 | freeenv_utf8(env_http_proxy); |
| 272 | return err < 0 ? err : http_connect( | ||
| 273 | h, path, local_path, hoststr, auth, proxyauth); | ||
| 268 | } | 274 | } |
| 269 | 275 | ||
| 270 | static int http_should_reconnect(HTTPContext *s, int err) | 276 | static int http_should_reconnect(HTTPContext *s, int err) |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "libavutil/avstring.h" | 22 | #include "libavutil/avstring.h" |
| 23 | #include "libavutil/getenv_utf8.h" | ||
| 23 | #include "libavutil/opt.h" | 24 | #include "libavutil/opt.h" |
| 24 | #include <sys/stat.h> | 25 | #include <sys/stat.h> |
| 25 | #include "os_support.h" | 26 | #include "os_support.h" |
| @@ -55,12 +56,15 @@ static int populate_ipfs_gateway(URLContext *h) · 29 unmodified lines | |||
| 55 | int stat_ret = 0; | 56 | int stat_ret = 0; |
| 56 | int ret = AVERROR(EINVAL); | 57 | int ret = AVERROR(EINVAL); |
| 57 | FILE *gateway_file = NULL; | 58 | FILE *gateway_file = NULL; |
| 59 | char *env_ipfs_gateway, *env_ipfs_path; | ||
| 58 | 60 | ||
| 59 | // Test $IPFS_GATEWAY. | 61 | // Test $IPFS_GATEWAY. |
| 60 | if (getenv("IPFS_GATEWAY") != NULL) { | 62 | env_ipfs_gateway = getenv_utf8("IPFS_GATEWAY"); |
| 61 | if (snprintf(c->gateway_buffer, sizeof(c->gateway_buffer), "%s", | 63 | if (env_ipfs_gateway != NULL) { |
| 62 | getenv("IPFS_GATEWAY")) | 64 | int printed = snprintf(c->gateway_buffer, sizeof(c->gateway_buffer), |
| 63 | >= sizeof(c->gateway_buffer)) { | 65 | "%s", env_ipfs_gateway); |
| 66 | freeenv_utf8(env_ipfs_gateway); | ||
| 67 | if (printed >= sizeof(c->gateway_buffer)) { | ||
| 64 | av_log(h, AV_LOG_WARNING, | 68 | av_log(h, AV_LOG_WARNING, |
| 65 | "The IPFS_GATEWAY environment variable " | 69 | "The IPFS_GATEWAY environment variable " |
| 66 | "exceeds the maximum length. " | 70 | "exceeds the maximum length. " |
| @@ -77,20 +81,26 @@ static int populate_ipfs_gateway(URLContext *h) · 10 unmodified lines | |||
| 77 | 81 | ||
| 78 | // We need to know the IPFS folder to - eventually - read the contents of | 82 | // We need to know the IPFS folder to - eventually - read the contents of |
| 79 | // the "gateway" file which would tell us the gateway to use. | 83 | // the "gateway" file which would tell us the gateway to use. |
| 80 | if (getenv("IPFS_PATH") == NULL) { | 84 | env_ipfs_path = getenv_utf8("IPFS_PATH"); |
| 85 | if (env_ipfs_path == NULL) { | ||
| 86 | int printed; | ||
| 87 | char *env_home = getenv_utf8("HOME"); | ||
| 88 | |||
| 81 | av_log(h, AV_LOG_DEBUG, "$IPFS_PATH is empty.\n"); | 89 | av_log(h, AV_LOG_DEBUG, "$IPFS_PATH is empty.\n"); |
| 82 | 90 | ||
| 83 | // Try via the home folder. | 91 | // Try via the home folder. |
| 84 | if (getenv("HOME") == NULL) { | 92 | if (env_home == NULL) { |
| 85 | av_log(h, AV_LOG_WARNING, "$HOME appears to be empty.\n"); | 93 | av_log(h, AV_LOG_WARNING, "$HOME appears to be empty.\n"); |
| 86 | ret = AVERROR(EINVAL); | 94 | ret = AVERROR(EINVAL); |
| 87 | goto err; | 95 | goto err; |
| 88 | } | 96 | } |
| 89 | 97 | ||
| 90 | // Verify the composed path fits. | 98 | // Verify the composed path fits. |
| 91 | if (snprintf(ipfs_full_data_folder, sizeof(ipfs_full_data_folder), | 99 | printed = snprintf( |
| 92 | "%s/.ipfs/", getenv("HOME")) | 100 | ipfs_full_data_folder, sizeof(ipfs_full_data_folder), |
| 93 | >= sizeof(ipfs_full_data_folder)) { | 101 | "%s/.ipfs/", env_home); |
| 102 | freeenv_utf8(env_home); | ||
| 103 | if (printed >= sizeof(ipfs_full_data_folder)) { | ||
| 94 | av_log(h, AV_LOG_WARNING, | 104 | av_log(h, AV_LOG_WARNING, |
| 95 | "The IPFS data path exceeds the " | 105 | "The IPFS data path exceeds the " |
| 96 | "max path length (%zu)\n", | 106 | "max path length (%zu)\n", |
| @@ -113,9 +123,11 @@ static int populate_ipfs_gateway(URLContext *h) · 16 unmodified lines | |||
| 113 | goto err; | 123 | goto err; |
| 114 | } | 124 | } |
| 115 | } else { | 125 | } else { |
| 116 | if (snprintf(ipfs_full_data_folder, sizeof(ipfs_full_data_folder), "%s", | 126 | int printed = snprintf( |
| 117 | getenv("IPFS_PATH")) | 127 | ipfs_full_data_folder, sizeof(ipfs_full_data_folder), |
| 118 | >= sizeof(ipfs_full_data_folder)) { | 128 | "%s", env_ipfs_path); |
| 129 | freeenv_utf8(env_ipfs_path); | ||
| 130 | if (printed >= sizeof(ipfs_full_data_folder)) { | ||
| 119 | av_log(h, AV_LOG_WARNING, | 131 | av_log(h, AV_LOG_WARNING, |
| 120 | "The IPFS_PATH environment variable " | 132 | "The IPFS_PATH environment variable " |
| 121 | "exceeds the maximum length. " | 133 | "exceeds the maximum length. " |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 26 | #include "url.h" | 26 | #include "url.h" |
| 27 | #include "tls.h" | 27 | #include "tls.h" |
| 28 | #include "libavutil/avstring.h" | 28 | #include "libavutil/avstring.h" |
| 29 | #include "libavutil/getenv_utf8.h" | ||
| 29 | #include "libavutil/opt.h" | 30 | #include "libavutil/opt.h" |
| 30 | #include "libavutil/parseutils.h" | 31 | #include "libavutil/parseutils.h" |
| 31 | 32 | ||
| @@ -60,6 +61,7 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV · 28 unmodified lines | |||
| 60 | char buf[200], opts[50] = ""; | 61 | char buf[200], opts[50] = ""; |
| 61 | struct addrinfo hints = { 0 }, *ai = NULL; | 62 | struct addrinfo hints = { 0 }, *ai = NULL; |
| 62 | const char *proxy_path; | 63 | const char *proxy_path; |
| 64 | char *env_http_proxy, *env_no_proxy; | ||
| 63 | int use_proxy; | 65 | int use_proxy; |
| 64 | 66 | ||
| 65 | set_options(c, uri); | 67 | set_options(c, uri); |
| @@ -89,9 +91,13 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV · 23 unmodified lines | |||
| 89 | if (!c->host && !(c->host = av_strdup(c->underlying_host))) | 91 | if (!c->host && !(c->host = av_strdup(c->underlying_host))) |
| 90 | return AVERROR(ENOMEM); | 92 | return AVERROR(ENOMEM); |
| 91 | 93 | ||
| 92 | proxy_path = c->http_proxy ? c->http_proxy : getenv("http_proxy"); | 94 | env_http_proxy = getenv_utf8("http_proxy"); |
| 93 | use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), c->underlying_host) && | 95 | proxy_path = c->http_proxy ? c->http_proxy : env_http_proxy; |
| 96 | |||
| 97 | env_no_proxy = getenv_utf8("no_proxy"); | ||
| 98 | use_proxy = !ff_http_match_no_proxy(env_no_proxy, c->underlying_host) && | ||
| 94 | proxy_path && av_strstart(proxy_path, "http://", NULL); | 99 | proxy_path && av_strstart(proxy_path, "http://", NULL); |
| 100 | freeenv_utf8(env_no_proxy); | ||
| 95 | 101 | ||
| 96 | if (use_proxy) { | 102 | if (use_proxy) { |
| 97 | char proxy_host[200], proxy_auth[200], dest[200]; | 103 | 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 · 6 unmodified lines | |||
| 104 | proxy_port, "/%s", dest); | 110 | proxy_port, "/%s", dest); |
| 105 | } | 111 | } |
| 106 | 112 | ||
| 113 | freeenv_utf8(env_http_proxy); | ||
| 107 | return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE, | 114 | return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE, |
| 108 | &parent->interrupt_callback, options, | 115 | &parent->interrupt_callback, options, |
| 109 | parent->protocol_whitelist, parent->protocol_blacklist, parent); | 116 | parent->protocol_whitelist, parent->protocol_blacklist, parent); |