changeset bb7da41dc997 in /home/hg/repos/gajim
details:http://hg.gajim.org/gajim?cmd=changeset;node=bb7da41dc997 description: more secure tmp file creation for latex
diffstat:
src/common/latex.py | 65 +++++++++++++++++++++++++--------------------------- 1 files changed, 31 insertions(+), 34 deletions(-)
diffs (141 lines):
diff -r 1c99366f6791 -r bb7da41dc997 src/common/latex.py --- a/src/common/latex.py Mon Apr 16 23:03:30 2012 +0200 +++ b/src/common/latex.py Tue Apr 17 10:45:55 2012 +0200 @@ -29,7 +29,7 @@
import os import random -from tempfile import gettempdir +from tempfile import mkstemp, mkdtemp from subprocess import Popen, PIPE
import logging @@ -57,24 +57,6 @@ return True return False
-def get_tmpfile_name(): - random.seed() - nb = 0 - while(nb < 100): - int_ = random.randint(0, 10000) - filename = os.path.join(gettempdir(), 'gajimtex_' + int_.__str__()) - # Check if a file to not overwrite it - ok = True - extensions = ['.tex', '.log', '.aux', '.dvi'] - for ext in extensions: - if os.path.exists(filename + ext): - ok = False - break - if ok: - return filename - nb += 1 - return filename - def write_latex(filename, str_): texstr = '\documentclass[12pt]{article}\usepackage[dvips]{graphicx}' texstr += '\usepackage{amsmath}\usepackage{amssymb}' @@ -91,12 +73,13 @@ # a wrapper for Popen so that no window gets opened on Windows # (i think this is the reason we're using Popen rather than just system()) # stdout goes to a pipe so that it can be read -def popen_nt_friendly(command): +def popen_nt_friendly(command, directory): if os.name == 'nt': # CREATE_NO_WINDOW - return Popen(command, creationflags=0x08000000, cwd=gettempdir(), stdout=PIPE) + return Popen(command, creationflags=0x08000000, cwd=directory, + stdout=PIPE) else: - return Popen(command, cwd=gettempdir(), stdout=PIPE) + return Popen(command, cwd=directory, stdout=PIPE)
def check_for_latex_support(): """ @@ -112,16 +95,16 @@ except LatexError: return False
-def try_run(argv): +def try_run(argv, directory): try: - p = popen_nt_friendly(argv) + p = popen_nt_friendly(argv, directory) out = p.communicate()[0] log.info(out) return p.wait() except Exception, e: return _('Error executing "%(command)s": %(error)s') % { - 'command': " ".join(argv), - 'error': helpers.decode_string(str(e))} + 'command': " ".join(argv), + 'error': helpers.decode_string(str(e))}
def latex_to_image(str_): @@ -137,32 +120,41 @@ return [] except AttributeError: # interface may not be available when we test latext at startup - return ['-fg', 'rgb 0.0 0.0 0.0'] + return {'hex': ['+level-colors', '0x000000'], + 'tex': ['-fg', 'rgb 0.0 0.0 0.0']}[fmt]
# filter latex code with bad commands if check_blacklist(str_): # we triggered the blacklist, immediately return None return None
- tmpfile = get_tmpfile_name() + try: + tmpdir = mkdtemp(prefix='gajimtex') + tmppng = mkstemp(prefix='gajim_tex', suffix='.png')[1] + except Exception: + raise LatexError('could not securely create one or more temporary files' + ' for LaTeX conversion') + + tmpfile = os.path.join(tmpdir, 'gajim_tex')
# build latex string - write_latex(os.path.join(tmpfile + '.tex'), str_) + write_latex(tmpfile + '.tex', str_)
# convert TeX to dvi - exitcode = try_run(['latex', '--interaction=nonstopmode', - tmpfile + '.tex']) + exitcode = try_run(['latex', '--interaction=nonstopmode', tmpfile + '.tex'], + tmpdir)
if exitcode == 0: # convert dvi to png latex_png_dpi = gajim.config.get('latex_png_dpi') exitcode = try_run(['dvipng'] + fg_str('tex') + ['-T', 'tight', '-D', - latex_png_dpi, tmpfile + '.dvi', '-o', tmpfile + '.png']) + latex_png_dpi, tmpfile + '.dvi', '-o', tmpfile + '.png'], tmpdir)
if exitcode: # dvipng failed, try convert exitcode = try_run(['convert'] + fg_str('hex') + ['-trim', - '-density', latex_png_dpi, tmpfile + '.dvi', tmpfile + '.png']) + '-density', latex_png_dpi, tmpfile + '.dvi', tmpfile + '.png'], + tmpdir)
# remove temp files created by us and TeX extensions = ['.tex', '.log', '.aux', '.dvi'] @@ -172,10 +164,15 @@ except Exception: pass
+ if exitcode == 0: + os.rename(tmpfile + '.png', tmppng) + + os.rmdir(tmpdir) + if isinstance(exitcode, (unicode, str)): raise LatexError(exitcode)
if exitcode == 0: - result = tmpfile + '.png' + result = tmppng
return result