Skip to content

Commit

Permalink
make_temp_file__: New function.
Browse files Browse the repository at this point in the history
Try to create temporary file in the most secure and portable way
possible.

Partially fixes gnu-octave#1145.

* inst/make_temp_file__.m: New function.
* inst/@sym/sym.m: Use it.
* inst/private/python_ipc_system.m: Use it.
  • Loading branch information
Alex Vong authored and Alex Vong committed Jul 6, 2022
1 parent 1dd9197 commit 4763104
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
3 changes: 2 additions & 1 deletion inst/@sym/sym.m
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
%% Copyright (C) 2014-2019, 2022 Colin B. Macdonald
%% Copyright (C) 2016 Lagu
%% Copyright (C) 2022 Alex Vong
%%
%% This file is part of OctSymPy.
%%
Expand Down Expand Up @@ -953,7 +954,7 @@
%! syms x
%! y = 2*x;
%! a = 42;
%! myfile = tempname ();
%! [fd, myfile] = make_temp_file__ (tempdir (), 'octsympy-myfile-');
%! save (myfile, 'x', 'y', 'a')
%! clear x y a
%! load (myfile)
Expand Down
78 changes: 78 additions & 0 deletions inst/make_temp_file__.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
%% Copyright (C) 2022 Alex Vong
%%
%% This file is part of OctSymPy.
%%
%% OctSymPy is free software; you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published
%% by the Free Software Foundation; either version 3 of the License,
%% or (at your option) any later version.
%%
%% This software is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty
%% of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
%% the GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public
%% License along with this software; see the file COPYING.
%% If not, see <https://www.gnu.org/licenses/>.

%% -*- texinfo -*-
%% @documentencoding UTF-8
%% @deftypefun {[@var{fd}, @var{filename}] =} make_temp_file__ (@var{tmpdir}, @var{prefix})
%% Try to create temporary file in temporary directory @var{tmpdir} with prefix
%% @var{prefix} in the most secure and portable way possible.
%%
%% This function is not really intended for end users.
%%
%% @end deftypefun


%% This function is used in private/python_ipc_*.m
%% Assume Python IPC is not initialized yet

function [fd, filename] = make_temp_file__ (tmpdir, prefix)
if (exist ('OCTAVE_VERSION', 'builtin'))
template = [tmpdir '/' prefix 'XXXXXX'];
[fd, filename, msg] = mkstemp (template);
if (fd == -1 || isequal (filename, ''))
error ('make_temp_file__: cannot create temp file: %s', msg);
end

elseif (usejava ('jvm')) % java is required when not running octave
attrs = javaArray ('java.nio.file.attribute.FileAttribute', 0);
path = javaMethod ('createTempFile', 'java.nio.file.Files',
prefix, '',
attrs);
filename = javaMethod ('toString', path);
fd = fopen (filename, 'r+');

else
error ('make_temp_file__: cannot create temp file: please enable java');
end
end


%!test
%! % general test
%! [fd, filename] = make_temp_file__ (tempdir (), 'octsympy-');
%! assert (~isempty (strfind (filename, tempdir ())));
%! assert (~isempty (strfind (filename, 'octsympy-')));
%! assert (mod (fd, 1) == 0 && fd > 2);
%! s = 'hello, world';
%! fprintf (fd, s);
%! assert (fclose (fd) == 0);
%! fd2 = fopen (filename);
%! s2 = fgets (fd2);
%! assert (isequal (s, s2));
%! assert (fgets (fd2) == -1);
%! assert (fclose (fd2) == 0);
%! if (exist ('OCTAVE_VERSION', 'builtin'))
%! assert (unlink (filename) == 0);
%! else
%! delete (filename);
%! end

%!error <cannot create temp file>
%! if (exist ('OCTAVE_VERSION', 'builtin'))
%! make_temp_file__ ('/nonexistent', '');
%! end
6 changes: 4 additions & 2 deletions inst/private/python_ipc_system.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
%% Copyright (C) 2014-2016, 2022 Colin B. Macdonald
%% Copyright (C) 2022 Alex Vong
%%
%% This file is part of OctSymPy.
%%
Expand Down Expand Up @@ -108,12 +109,13 @@
%% Generate a temp .py file then execute it with system()
% can be useful for debugging, or if "python -c" fails for you
if (isempty (tmpfilename))
tmpfilename = [tempname() '_octsympytmp.py'];
[fd, tmpfilename] = make_temp_file__ (tempdir (), 'octsympy-tmpfile-');
if (verbose)
disp (['This session will use the temp file "' tmpfilename '"'])
end
else
fd = fopen (tmpfilename, 'w');
end
fd = fopen (tmpfilename, 'w');
fprintf(fd, '# temporary autogenerated code\n\n');
% we just added two more lines at the top
info.prelines = info.prelines + 2;
Expand Down

0 comments on commit 4763104

Please sign in to comment.