Skip to content

Commit 4a60001

Browse files
author
Release Manager
committed
gh-36436: src/sage/misc/latex.py: replace tmp_dir() These bits of code only use one temporary file, but they call a function `_run_latex_()` that writes its output file to the same directory as its input file. Since we don't want the output path to be predictable (for security reasons), we have to "hide" the one temporary file inside of a temporary directory that will only be writable by the Sage user. In other words: standard `tempfile.TemporaryDirecrory()` replacement. Issue: #36322 URL: #36436 Reported by: Michael Orlitzky Reviewer(s): Marc Mezzarobba
2 parents 7e74664 + 0c4578f commit 4a60001

File tree

1 file changed

+77
-71
lines changed

1 file changed

+77
-71
lines changed

src/sage/misc/latex.py

Lines changed: 77 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
import re
3131
import shutil
3232
from subprocess import call, PIPE
33+
from tempfile import TemporaryDirectory
3334

3435
from sage.misc.cachefunc import cached_function, cached_method
35-
from sage.misc.temporary_file import tmp_dir
3636
from sage.structure.sage_object import SageObject
3737

3838
from sage.misc.lazy_import import lazy_import
@@ -1103,44 +1103,49 @@ def eval(self, x, globals, strip=False, filename=None, debug=None,
11031103
filename = 'sage%s' % random.randint(1, 100) # to defeat browser caches
11041104
else:
11051105
filename = os.path.splitext(filename)[0] # get rid of extension
1106-
base = tmp_dir()
1107-
orig_base, filename = os.path.split(os.path.abspath(filename))
1108-
if len(filename.split()) > 1:
1109-
raise ValueError("filename must contain no spaces")
1110-
if debug is None:
1111-
debug = self.__debug
1112-
x = self._latex_preparse(x, locals)
1113-
O = open(os.path.join(base, filename + ".tex"), 'w')
1114-
if self.__slide:
1115-
O.write(SLIDE_HEADER)
1116-
O.write(MACROS)
1117-
O.write('\\begin{document}\n\n')
1118-
else:
1119-
O.write(LATEX_HEADER)
1120-
O.write(MACROS)
1121-
O.write('\\begin{document}\n')
11221106

1123-
O.write(x)
1124-
if self.__slide:
1125-
O.write('\n\n\\end{document}')
1126-
else:
1127-
O.write('\n\n\\end{document}\n')
1107+
result = None
1108+
with TemporaryDirectory() as base:
1109+
orig_base, filename = os.path.split(os.path.abspath(filename))
1110+
if len(filename.split()) > 1:
1111+
raise ValueError("filename must contain no spaces")
1112+
if debug is None:
1113+
debug = self.__debug
1114+
x = self._latex_preparse(x, locals)
1115+
O = open(os.path.join(base, filename + ".tex"), 'w')
1116+
if self.__slide:
1117+
O.write(SLIDE_HEADER)
1118+
O.write(MACROS)
1119+
O.write('\\begin{document}\n\n')
1120+
else:
1121+
O.write(LATEX_HEADER)
1122+
O.write(MACROS)
1123+
O.write('\\begin{document}\n')
11281124

1129-
O.close()
1130-
if engine is None:
1131-
if self.__engine is None:
1132-
engine = _Latex_prefs._option["engine"]
1125+
O.write(x)
1126+
if self.__slide:
1127+
O.write('\n\n\\end{document}')
11331128
else:
1134-
engine = self.__engine
1135-
e = _run_latex_(os.path.join(base, filename + ".tex"), debug=debug,
1136-
density=density, engine=engine, png=True)
1137-
if e.find("Error") == -1:
1138-
shutil.copy(os.path.join(base, filename + ".png"),
1139-
os.path.join(orig_base, filename + ".png"))
1140-
shutil.rmtree(base)
1141-
return ''
1142-
else:
1143-
return
1129+
O.write('\n\n\\end{document}\n')
1130+
1131+
O.close()
1132+
if engine is None:
1133+
if self.__engine is None:
1134+
engine = _Latex_prefs._option["engine"]
1135+
else:
1136+
engine = self.__engine
1137+
e = _run_latex_(os.path.join(base, filename + ".tex"),
1138+
debug=debug,
1139+
density=density,
1140+
engine=engine,
1141+
png=True)
1142+
1143+
if e.find("Error") == -1:
1144+
shutil.copy(os.path.join(base, filename + ".png"),
1145+
os.path.join(orig_base, filename + ".png"))
1146+
result = ''
1147+
1148+
return result
11441149

11451150
def blackboard_bold(self, t=None):
11461151
r"""nodetex
@@ -1918,27 +1923,27 @@ def view(objects, title='Sage', debug=False, sep='', tiny=False,
19181923
if pdflatex or (viewer == "pdf" and engine == "latex"):
19191924
engine = "pdflatex"
19201925
# command line or notebook with viewer
1921-
tmp = tmp_dir('sage_viewer')
1922-
tex_file = os.path.join(tmp, "sage.tex")
1923-
with open(tex_file, 'w') as file:
1924-
file.write(s)
1925-
suffix = _run_latex_(tex_file, debug=debug, engine=engine, png=False)
1926-
if suffix == "pdf":
1927-
from sage.misc.viewer import pdf_viewer
1928-
viewer = pdf_viewer()
1929-
elif suffix == "dvi":
1930-
from sage.misc.viewer import dvi_viewer
1931-
viewer = dvi_viewer()
1932-
else:
1933-
print("Latex error")
1934-
return
1935-
output_file = os.path.join(tmp, "sage." + suffix)
1936-
# this should get changed if we switch the stuff in misc.viewer to
1937-
# producing lists
1938-
if debug:
1939-
print('viewer: "{}"'.format(viewer))
1940-
call('%s %s' % (viewer, output_file), shell=True,
1941-
stdout=PIPE, stderr=PIPE)
1926+
with TemporaryDirectory() as tmp:
1927+
tex_file = os.path.join(tmp, "sage.tex")
1928+
with open(tex_file, 'w') as file:
1929+
file.write(s)
1930+
suffix = _run_latex_(tex_file, debug=debug, engine=engine, png=False)
1931+
if suffix == "pdf":
1932+
from sage.misc.viewer import pdf_viewer
1933+
viewer = pdf_viewer()
1934+
elif suffix == "dvi":
1935+
from sage.misc.viewer import dvi_viewer
1936+
viewer = dvi_viewer()
1937+
else:
1938+
print("Latex error")
1939+
return
1940+
output_file = os.path.join(tmp, "sage." + suffix)
1941+
# this should get changed if we switch the stuff in misc.viewer to
1942+
# producing lists
1943+
if debug:
1944+
print('viewer: "{}"'.format(viewer))
1945+
call('%s %s' % (viewer, output_file), shell=True,
1946+
stdout=PIPE, stderr=PIPE)
19421947
return
19431948

19441949

@@ -1990,20 +1995,21 @@ def png(x, filename, density=150, debug=False,
19901995
# path name for permanent png output
19911996
abs_path_to_png = os.path.abspath(filename)
19921997
# temporary directory to store stuff
1993-
tmp = tmp_dir('sage_viewer')
1994-
tex_file = os.path.join(tmp, "sage.tex")
1995-
png_file = os.path.join(tmp, "sage.png")
1996-
# write latex string to file
1997-
with open(tex_file, 'w') as file:
1998-
file.write(s)
1999-
# run latex on the file, producing png output to png_file
2000-
e = _run_latex_(tex_file, density=density, debug=debug,
2001-
png=True, engine=engine)
2002-
if e.find("Error") == -1:
2003-
# if no errors, copy png_file to the appropriate place
2004-
shutil.copy(png_file, abs_path_to_png)
2005-
else:
2006-
print("Latex error")
1998+
with TemporaryDirectory() as tmp:
1999+
tex_file = os.path.join(tmp, "sage.tex")
2000+
png_file = os.path.join(tmp, "sage.png")
2001+
# write latex string to file
2002+
with open(tex_file, 'w') as file:
2003+
file.write(s)
2004+
# run latex on the file, producing png output to png_file
2005+
e = _run_latex_(tex_file, density=density, debug=debug,
2006+
png=True, engine=engine)
2007+
if e.find("Error") == -1:
2008+
# if no errors, copy png_file to the appropriate place
2009+
shutil.copy(png_file, abs_path_to_png)
2010+
else:
2011+
print("Latex error")
2012+
20072013
if debug:
20082014
return s
20092015
return

0 commit comments

Comments
 (0)