From patchwork Tue Aug 28 05:11:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gyan X-Patchwork-Id: 10158 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:12c4:0:0:0:0:0 with SMTP id 65-v6csp7202244jap; Mon, 27 Aug 2018 22:11:53 -0700 (PDT) X-Google-Smtp-Source: ANB0VdattIWmtHZLLA0Ck0bhs3bcSyeLLk8Y93cbopezNR2Og2Oxe2Sj3sUl4wkXrROOnbLyZ7a4 X-Received: by 2002:adf:f648:: with SMTP id x8-v6mr10962239wrp.144.1535433113534; Mon, 27 Aug 2018 22:11:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535433113; cv=none; d=google.com; s=arc-20160816; b=uocaBrILh254YCt5RNQlmhIl5VdPdP707zX3bOUcDfdeAp41WHKq6hL25/kEf9Kim8 aHWgrHp7UFaH09g4PYd7bdPwhripI8mYxVEN1MrtMx2iE7tlC9mkJG+leAAbnRmJSsKs fKjRItosL752sLML4MwNXgzenA/Q8ypCaDYbzVxcPo2ARgP47PSa4cpgmMao6YDOQ9aA imAVt7GF8Bdb5tPsjG4DKoWGnuEZ4zL5ixvzqpBnUO/zJZ1ZZ7gmx6bC+R78xXMlHQOX 1Wz1Kxm2BgNr4CoVDUAFZ0mnyXSkjEuGsgTBiQ9jfQI++Q+KBWHowagyLhnrlHfD0pnQ JzaQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject :content-language:mime-version:user-agent:date:message-id:from:to :dkim-signature:delivered-to:arc-authentication-results; bh=0qMRgqBw8n6d4LJj55cweOhpfJUy/nc6/nU9rvom3kM=; b=Zs+F8wxkdYxQnhLltA5sLv+874KE8jbohYjJbZwrwZ11y/d1SnqzjWjfq2/0Soy3YG eswQDrNxDS9CPJZFBJbpOU5HRu/T4xb0f8rWMi7JtzKTgGivqXn+EDO1+vzi7YWu91MX rOp+2I6xgUZpgOf8Rr5bF5B9VDllU8cSOilF46irCsCxDQkGlEX2QBgwmohyop4/zPG6 hUKPOTkkP4HEYd8bMbg9ngwp55pC9WMxY5toEXBymavHohRkZGGEGwU+sRgk983xV53M ghamDQeLf9jSApiAuHienIzDDA6EfvZ+0nWnwPSyB+bQttqkvCJC0Y5oYgqFv4hWzlDU OGWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=YPMCeGgy; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id j140-v6si277635wmd.76.2018.08.27.22.11.52; Mon, 27 Aug 2018 22:11:53 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=YPMCeGgy; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3EE54688346; Tue, 28 Aug 2018 08:11:47 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 17A5F6809D4 for ; Tue, 28 Aug 2018 08:11:40 +0300 (EEST) Received: by mail-pg1-f175.google.com with SMTP id d19-v6so232300pgv.1 for ; Mon, 27 Aug 2018 22:11:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=EjkRt0aY2r+wCwfgTG0b79kSccSDk1G9bes3ZmZA+rw=; b=YPMCeGgyK0sSQjmf5YwPwqjf4VLo1re4HCJvlfGcVb9+/s1jq78Bv9culmLdbXAW8F AM5vAEmXVmNKQ2bcLwpgVIYq7O2N48W19RLJ2pj+nBGrKE/N01Py7m16o47BfblMFnq5 pJw/3hL7GVUPLgvmZV00A88UiUkVVO3rmv9JWoSPpsp2IqOJwlpjQWcYnkTrhbgThT4+ cK7CX8hectuI3OqPINr4blbo28wcbJFkIfJS+zZ3JQJOBHyoYOW3SDQ+FueEs0imxe2o q9sDiW2b4UgJCTvASMBV4GkUw/WvsfIMaCIkcaaWeH4Fn/w5467RWcspxP5q6yRuG2GZ TeKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language; bh=EjkRt0aY2r+wCwfgTG0b79kSccSDk1G9bes3ZmZA+rw=; b=WONRw1hNwnid45mxtOAzCspL5cUARhLYy2pLvoz2LzMHQ+egULRJdFCDMpvQQAOXlS d03RV40RBdYiVOTj+4/Qox2EyoXIoFKs3jUCsyzDpCf3VUnfNZ8OX15L3Rris/LwTQN5 j69/tu8RZxVGDsYPVBZcJhhhAJfBDkMJn51D7+3zYZwT13LUBGy3yxLvkOJuX+sPAoNq RRTkFnJP8hBoJaQSEAQbgfQBlQabH6LnSGeAgrLyvH3t0RRN3wX6tL33LhKdw+yJpXS8 qMxVP1fLDpUR9SWSJqBKV3UDNia1jlJebsmoVBXOW52m2YhR2o+KUZHi2dSPTo3ODaM4 ny2A== X-Gm-Message-State: APzg51CvNAa7ePJaNqymZGCqL/kExG1lfg4xniLmPZ+GHJ8uqHfdjc9Q EThLm6hHlk56Kwj6e3aT/Bv1rQU6 X-Received: by 2002:a62:ea05:: with SMTP id t5-v6mr17266121pfh.228.1535433101242; Mon, 27 Aug 2018 22:11:41 -0700 (PDT) Received: from [192.168.1.225] ([183.87.90.192]) by smtp.gmail.com with ESMTPSA id f184-v6sm242802pfc.88.2018.08.27.22.11.39 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 27 Aug 2018 22:11:40 -0700 (PDT) To: ffmpeg-devel@ffmpeg.org From: Gyan Doshi Message-ID: <169c1509-0128-5e3d-1949-cd65f7a7aad0@gmail.com> Date: Tue, 28 Aug 2018 10:41:36 +0530 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 Content-Language: en-US Subject: [FFmpeg-devel] [PATCH] ffmpeg: block output == input for files X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" With some regularity, we have users trying to update input files using ffmpeg, usually for the purposes of tagging, but occasionally for changing the encoding or something else. Other apps like mp4box or taggers edit the files in-place i.e. destination file is same as the source. FFmpeg cannot do this. But since these users don't realize that, they will answer Yes to the overwrite prompt and then discover their source has been destroyed. Attached patch checks the URL for file protocol outputs against inputs and aborts upon a match. An option is provided for the user to force the operation. The check isn't robust. In particular, it looks for exact url string matches, so a command like ffmpeg -i file:somefile -some_op somefile will still pass through. But I consider such invocations rare. Most times I've seen users trying this (on Stackexchange or other support forums), the command is typically of the form, for i; do ffmpeg -i $i -some_op -y $i Such a scenario was filed as a bug in #4655 but it was marked as wontfix since some protocols/services can manage bidir ops to the same endpoint. For that reason, everything other than file protocol sources/sinks are exempt i.e. http, pipes, devices..etc. This patch doesn't affect the semantics of '-y' and adds the check after it. Thanks, Gyan From deb97d9b5dd1f50a7e6b560c77b81b9cd707b7c1 Mon Sep 17 00:00:00 2001 From: Gyan Doshi Date: Sun, 26 Aug 2018 11:22:50 +0530 Subject: [PATCH] ffmpeg: block output == input for files Add option write_to_input_file to allow it. Fixes #4655 --- doc/ffmpeg.texi | 6 ++++++ fftools/ffmpeg.h | 1 + fftools/ffmpeg_opt.c | 20 +++++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 3717f22d42..6fb359eabe 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -445,6 +445,12 @@ Overwrite output files without asking. Do not overwrite output files, and exit immediately if a specified output file already exists. +@item -write_to_input_file (@emph{global}) +Allow writing to an input file. Normally, this will destroy the input file and +the conversion will fail, as FFmpeg does not perform in-place editing. But some +protocols or storage services can accommodate this use-case. Verify before setting it. +This option does not override the generic output overwrite check. Disabled by default. + @item -stream_loop @var{number} (@emph{input}) Set number of times input stream shall be looped. Loop 0 means no loop, loop -1 means infinite loop. diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index eb1eaf6363..6c1f87c7ad 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -606,6 +606,7 @@ extern int frame_bits_per_raw_sample; extern AVIOContext *progress_avio; extern float max_error_rate; extern char *videotoolbox_pixfmt; +extern int write_to_input_file; extern int filter_nbthreads; extern int filter_complex_nbthreads; diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 58ec13e5a8..74e9b94bf5 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -121,6 +121,7 @@ static int input_stream_potentially_available = 0; static int ignore_unknown_streams = 0; static int copy_unknown_streams = 0; static int find_stream_info = 1; +extern int write_to_input_file = 0; static void uninit_options(OptionsContext *o) { @@ -900,13 +901,14 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) static void assert_file_overwrite(const char *filename) { + const char *proto_name = avio_find_protocol_name(filename); + if (file_overwrite && no_file_overwrite) { fprintf(stderr, "Error, both -y and -n supplied. Exiting.\n"); exit_program(1); } if (!file_overwrite) { - const char *proto_name = avio_find_protocol_name(filename); if (proto_name && !strcmp(proto_name, "file") && avio_check(filename, 0) == 0) { if (stdin_interaction && !no_file_overwrite) { fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename); @@ -925,6 +927,20 @@ static void assert_file_overwrite(const char *filename) } } } + + if (!write_to_input_file && proto_name && !strcmp(proto_name, "file")) { + for (int i = 0; i < nb_input_files; i++) { + InputFile *file = input_files[i]; + if (file->ctx->iformat->flags & AVFMT_NOFILE) + continue; + if (!strcmp(filename, file->ctx->url)) { + av_log(NULL, AV_LOG_FATAL, "Output same as Input #%d - exiting\n", i); + av_log(NULL, AV_LOG_WARNING, "FFmpeg cannot edit existing files in-place.\n" + "Add -write_to_input_file if this is a safe operation and intended.\n"); + exit_program(1); + } + } + } } static void dump_attachment(AVStream *st, const char *filename) @@ -3315,6 +3331,8 @@ const OptionDef options[] = { "overwrite output files" }, { "n", OPT_BOOL, { &no_file_overwrite }, "never overwrite output files" }, + { "write_to_input_file", OPT_BOOL, { &write_to_input_file }, + "allow writing to an input file - normally destructive to input files and conversion may fail" }, { "ignore_unknown", OPT_BOOL, { &ignore_unknown_streams }, "Ignore unknown stream types" }, { "copy_unknown", OPT_BOOL | OPT_EXPERT, { ©_unknown_streams },