lyx_mirror/src/graphics/PreviewImage.cpp
Tommaso Cucinotta 244de5d2c1 Add 'needauth' option to converters that need explicit user authorization.
Addressing #10481.

This patch adds the new 'needauth' option for converters launching
external programs that are capable of running arbitrary code on behalf
of the user. These converters won't be run unless the user gives explicit
authorization, which is asked on-demand when the converter is about to
be run (question is not asked if the file is cached and calling the
converter is not needed).

The user prompt has a 3rd button so that he/she's not prompted again
for (any converter over) the same document (identified through
buffer->absFileName()).

Two preference options are added:

lyxrc.use_converter_needauth_forbidden disables any converter with
the 'needauth' option, which is meant to force user to an explicit
action via the preferences pane, before being able to use advanced
converters that can potentially bring security threats;

lyxrc.use_converter_needauth enables prompting the user for 'needauth'
converters, or bypasses the check if not enabled, falling back to the
previous behavior.

So, the first option is for maximum security, the second is for
maximum usability.
2016-11-22 23:54:58 +01:00

170 lines
3.2 KiB
C++

/**
* \file PreviewImage.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "PreviewImage.h"
#include "Buffer.h"
#include "Dimension.h"
#include "GraphicsImage.h"
#include "GraphicsLoader.h"
#include "PreviewLoader.h"
#include "support/FileName.h"
#include "support/bind.h"
using namespace std;
using namespace lyx::support;
namespace lyx {
namespace graphics {
class PreviewImage::Impl : public boost::signals2::trackable {
public:
///
Impl(PreviewImage & p, PreviewLoader & l,
string const & s, FileName const & f, double af);
///
~Impl();
///
Image const * image();
///
void statusChanged();
///
PreviewImage const & parent_;
///
PreviewLoader & ploader_;
///
Loader iloader_;
///
string const snippet_;
///
double const ascent_frac_;
};
PreviewImage::PreviewImage(PreviewLoader & l,
string const & s,
FileName const & f,
double af)
: pimpl_(new Impl(*this, l, s, f, af))
{}
PreviewImage::~PreviewImage()
{
delete pimpl_;
}
string const & PreviewImage::snippet() const
{
return pimpl_->snippet_;
}
support::FileName const & PreviewImage::filename() const
{
return pimpl_->iloader_.filename();
}
Dimension PreviewImage::dim() const
{
Dimension dim;
Image const * const image = pimpl_->iloader_.image();
if (!image)
return dim;
dim.asc = int(pimpl_->ascent_frac_ * double(image->height()) + 0.5);
dim.des = image->height() - dim.asc;
dim.wid = image->width();
return dim;
}
Image const * PreviewImage::image() const
{
return pimpl_->image();
}
PreviewLoader & PreviewImage::previewLoader() const
{
return pimpl_->ploader_;
}
PreviewImage::Impl::Impl(PreviewImage & p, PreviewLoader & l,
string const & s,
FileName const & bf,
double af)
: parent_(p), ploader_(l), iloader_(l.buffer().fileName(), bf),
snippet_(s), ascent_frac_(af)
{
iloader_.setDisplayPixelRatio(l.displayPixelRatio());
iloader_.connect(bind(&Impl::statusChanged, this));
}
PreviewImage::Impl::~Impl()
{
// If these images are generated for a clone, then that may be
// because we are previewing. We therefore do not want to delete
// them when this Buffer is destroyed.
if (!ploader_.buffer().isClone())
iloader_.filename().removeFile();
}
Image const * PreviewImage::Impl::image()
{
if (iloader_.status() == WaitingToLoad)
iloader_.startLoading();
return iloader_.image();
}
void PreviewImage::Impl::statusChanged()
{
switch (iloader_.status()) {
case WaitingToLoad:
case Loading:
case Converting:
case Loaded:
case ScalingEtc:
break;
case ErrorNoFile:
case ErrorConverting:
case ErrorLoading:
case ErrorGeneratingPixmap:
case ErrorUnknown:
//iloader_.filename().removeFile();
ploader_.remove(snippet_);
// FIXME: We need to return here, because PreviewLoader::remove
// removes the preview image from the cache, which deletes this
// object, so we should not try to do anything here.
return;
case Ready:
iloader_.filename().removeFile();
break;
}
ploader_.emitSignal(parent_);
}
} // namespace graphics
} // namespace lyx