Commit e188d0fffa60e20114fbbedb58f9e9a5e65778fd

Authored by Jay Berkenbilt
1 parent bcfb0c7d

Make --replace-input work with / in path (fixes #365)

ChangeLog
  1 +2019-10-12 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Change the name of the temporary file used by --replace-input to
  4 + work with arbitrary absolute or relative paths without requiring
  5 + path splitting logic. Fixes #365.
  6 +
1 2019-09-20 Jay Berkenbilt <ejb@ql.org> 7 2019-09-20 Jay Berkenbilt <ejb@ql.org>
2 8
3 * 9.0.1: release 9 * 9.0.1: release
manual/qpdf-manual.xml
@@ -458,7 +458,7 @@ make @@ -458,7 +458,7 @@ make
458 If specified, the output file name should be omitted. This 458 If specified, the output file name should be omitted. This
459 option tells qpdf to replace the input file with the output. 459 option tells qpdf to replace the input file with the output.
460 It does this by writing to 460 It does this by writing to
461 - <filename>.~qpdf-temp.<replaceable>infilename</replaceable>#</filename> 461 + <filename><replaceable>infilename</replaceable>.~qpdf-temp#</filename>
462 and, when done, overwriting the input file with the temporary 462 and, when done, overwriting the input file with the temporary
463 file. If there were any warnings, the original input is saved 463 file. If there were any warnings, the original input is saved
464 as 464 as
@@ -4365,6 +4365,27 @@ print &quot;\n&quot;; @@ -4365,6 +4365,27 @@ print &quot;\n&quot;;
4365 </para> 4365 </para>
4366 <variablelist> 4366 <variablelist>
4367 <varlistentry> 4367 <varlistentry>
  4368 + <term>9.0.2: XXX</term>
  4369 + <listitem>
  4370 + <itemizedlist>
  4371 + <listitem>
  4372 + <para>
  4373 + Bug Fix
  4374 + </para>
  4375 + <itemizedlist>
  4376 + <listitem>
  4377 + <para>
  4378 + Fix the name of the temporary file used by
  4379 + <option>--replace-input</option> so that it doesn't require
  4380 + path splitting and works with paths include directories.
  4381 + </para>
  4382 + </listitem>
  4383 + </itemizedlist>
  4384 + </listitem>
  4385 + </itemizedlist>
  4386 + </listitem>
  4387 + </varlistentry>
  4388 + <varlistentry>
4368 <term>9.0.1: September 20, 2019</term> 4389 <term>9.0.1: September 20, 2019</term>
4369 <listitem> 4390 <listitem>
4370 <itemizedlist> 4391 <itemizedlist>
qpdf/qpdf.cc
@@ -5148,11 +5148,10 @@ static void write_outfile(QPDF&amp; pdf, Options&amp; o) @@ -5148,11 +5148,10 @@ static void write_outfile(QPDF&amp; pdf, Options&amp; o)
5148 std::string temp_out; 5148 std::string temp_out;
5149 if (o.replace_input) 5149 if (o.replace_input)
5150 { 5150 {
5151 - // Use a file name that is hidden by default in the OS to  
5152 - // avoid having it become momentarily visible in a  
5153 - // graphical file manager or in case it gets left behind  
5154 - // because of some kind of error.  
5155 - temp_out = ".~qpdf-temp." + std::string(o.infilename) + "#"; 5151 + // Append but don't prepend to the path to generate a
  5152 + // temporary name. This saves us from having to split the path
  5153 + // by directory and non-directory.
  5154 + temp_out = std::string(o.infilename) + ".~qpdf-temp#";
5156 // o.outfilename will be restored to 0 before temp_out 5155 // o.outfilename will be restored to 0 before temp_out
5157 // goes out of scope. 5156 // goes out of scope.
5158 o.outfilename = temp_out.c_str(); 5157 o.outfilename = temp_out.c_str();
@@ -5180,18 +5179,11 @@ static void write_outfile(QPDF&amp; pdf, Options&amp; o) @@ -5180,18 +5179,11 @@ static void write_outfile(QPDF&amp; pdf, Options&amp; o)
5180 { 5179 {
5181 // We must close the input before we can rename files 5180 // We must close the input before we can rename files
5182 pdf.closeInputSource(); 5181 pdf.closeInputSource();
5183 - std::string backup; 5182 + std::string backup = std::string(o.infilename) + ".~qpdf-orig";
5184 bool warnings = pdf.anyWarnings(); 5183 bool warnings = pdf.anyWarnings();
5185 - if (warnings)  
5186 - {  
5187 - // If there are warnings, the user may care about this  
5188 - // file, so give it a non-hidden name that will be  
5189 - // lexically grouped with the original file.  
5190 - backup = std::string(o.infilename) + ".~qpdf-orig";  
5191 - }  
5192 - else 5184 + if (! warnings)
5193 { 5185 {
5194 - backup = ".~qpdf-orig." + std::string(o.infilename) + "#"; 5186 + backup.append(1, '#');
5195 } 5187 }
5196 QUtil::rename_file(o.infilename, backup.c_str()); 5188 QUtil::rename_file(o.infilename, backup.c_str());
5197 QUtil::rename_file(temp_out.c_str(), o.infilename); 5189 QUtil::rename_file(temp_out.c_str(), o.infilename);
qpdf/qtest/qpdf.test
@@ -207,7 +207,7 @@ foreach my $d ([&#39;auto-ü&#39;, 1], [&#39;auto-öπ&#39;, 2]) @@ -207,7 +207,7 @@ foreach my $d ([&#39;auto-ü&#39;, 1], [&#39;auto-öπ&#39;, 2])
207 my ($u, $n) = @$d; 207 my ($u, $n) = @$d;
208 $td->runtest("replace input $u", 208 $td->runtest("replace input $u",
209 {$td->COMMAND => "qpdf --deterministic-id" . 209 {$td->COMMAND => "qpdf --deterministic-id" .
210 - " --object-streams=generate --replace-input $u.pdf"}, 210 + " --object-streams=generate --replace-input ./$u.pdf"},
211 {$td->STRING => "", $td->EXIT_STATUS => 0}, 211 {$td->STRING => "", $td->EXIT_STATUS => 0},
212 $td->NORMALIZE_NEWLINES); 212 $td->NORMALIZE_NEWLINES);
213 $td->runtest("check output ($u)", 213 $td->runtest("check output ($u)",
@@ -219,7 +219,7 @@ foreach my $d ([&#39;auto-ü&#39;, 1], [&#39;auto-öπ&#39;, 2]) @@ -219,7 +219,7 @@ foreach my $d ([&#39;auto-ü&#39;, 1], [&#39;auto-öπ&#39;, 2])
219 system("cp xref-with-short-size.pdf auto-warn.pdf") == 0 or die; 219 system("cp xref-with-short-size.pdf auto-warn.pdf") == 0 or die;
220 $td->runtest("replace input with warnings", 220 $td->runtest("replace input with warnings",
221 {$td->COMMAND => 221 {$td->COMMAND =>
222 - "qpdf --deterministic-id --replace-input auto-warn.pdf"}, 222 + "qpdf --deterministic-id --replace-input ./auto-warn.pdf"},
223 {$td->FILE => "replace-warn.out", $td->EXIT_STATUS => 3}, 223 {$td->FILE => "replace-warn.out", $td->EXIT_STATUS => 3},
224 $td->NORMALIZE_NEWLINES); 224 $td->NORMALIZE_NEWLINES);
225 225
qpdf/qtest/qpdf/replace-warn.out
1 -WARNING: auto-warn.pdf (xref stream, offset 16227): Cross-reference stream data has the wrong size; expected = 52; actual = 56  
2 -qpdf: there are warnings; original file kept in auto-warn.pdf.~qpdf-orig 1 +WARNING: ./auto-warn.pdf (xref stream, offset 16227): Cross-reference stream data has the wrong size; expected = 52; actual = 56
  2 +qpdf: there are warnings; original file kept in ./auto-warn.pdf.~qpdf-orig
3 qpdf: operation succeeded with warnings; resulting file may have some problems 3 qpdf: operation succeeded with warnings; resulting file may have some problems