Make sure helper apps we start are in path

QProcess will happily start things in CWD which is not what we want
remotes/origin/release/21.12
Albert Astals Cid 4 years ago
parent 715fd1ac36
commit feef900250
  1. 11
      core/document.cpp
  2. 51
      generators/dvi/dviFile.cpp
  3. 2
      generators/dvi/dviFile.h
  4. 15
      generators/dvi/dviRenderer_prescan.cpp
  5. 10
      generators/dvi/fontEncoding.cpp
  6. 8
      generators/dvi/fontMap.cpp
  7. 9
      generators/dvi/fontpool.cpp
  8. 18
      generators/dvi/psgs.cpp

@ -4202,11 +4202,18 @@ void Document::processSourceReference(const SourceReference *ref)
const QString cmd = KMacroExpander::expandMacrosShellQuote(p, map); const QString cmd = KMacroExpander::expandMacrosShellQuote(p, map);
if (cmd.isEmpty()) if (cmd.isEmpty())
return; return;
const QStringList args = KShell::splitArgs(cmd); QStringList args = KShell::splitArgs(cmd);
if (args.isEmpty()) if (args.isEmpty())
return; return;
KProcess::startDetached(args); const QString prog = args.takeFirst();
// Make sure prog is in PATH and not just in the CWD
const QString progFullPath = QStandardPaths::findExecutable(prog);
if (progFullPath.isEmpty()) {
return;
}
KProcess::startDetached(progFullPath, args);
} }
const SourceReference *Document::dynamicSourceReference(int pageNr, double absX, double absY) const SourceReference *Document::dynamicSourceReference(int pageNr, double absX, double absY)

@ -43,6 +43,7 @@
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QProcess> #include <QProcess>
#include <QStandardPaths>
#include <QSysInfo> #include <QSysInfo>
#include <QTemporaryFile> #include <QTemporaryFile>
@ -332,6 +333,28 @@ void dvifile::renumber()
} }
} }
void dvifile::pdf2psNotFound(const QString &PDFFilename, QString *converrorms)
{
// Indicates that conversion failed, won't try again.
convertedFiles[PDFFilename].clear();
if (converrorms != nullptr && !have_complainedAboutMissingPDF2PS) {
*converrorms = i18n(
"<qt><p>The external program <strong>pdf2ps</strong> could not be started. As a result, "
"the PDF-file %1 could not be converted to PostScript. Some graphic elements in your "
"document will therefore not be displayed.</p>"
"<p><b>Possible reason:</b> The program <strong>pdf2ps</strong> may not be installed "
"on your system, or cannot be found in the current search path.</p>"
"<p><b>What you can do:</b> The program <strong>pdf2ps</strong> is normally "
"contained in distributions of the ghostscript PostScript interpreter system. If "
"ghostscript is not installed on your system, you could install it now. "
"If you are sure that ghostscript is installed, try to use <strong>pdf2ps</strong> "
"from the command line to check if it really works.</p><p><em>PATH:</em> %2</p></qt>",
PDFFilename,
QString::fromLocal8Bit(qgetenv("PATH")));
have_complainedAboutMissingPDF2PS = true;
}
}
QString dvifile::convertPDFtoPS(const QString &PDFFilename, QString *converrorms) QString dvifile::convertPDFtoPS(const QString &PDFFilename, QString *converrorms)
{ {
// Check if the PDFFile is known // Check if the PDFFile is known
@ -341,6 +364,13 @@ QString dvifile::convertPDFtoPS(const QString &PDFFilename, QString *converrorms
return it.value(); return it.value();
} }
// Make sure pdf2ps is in PATH and not just in the CWD
static const QString fullPath = QStandardPaths::findExecutable(QStringLiteral("pdf2ps"));
if (!fullPath.isEmpty()) {
pdf2psNotFound(PDFFilename, converrorms);
return QString();
}
// Get the name of a temporary file. // Get the name of a temporary file.
// Must open the QTemporaryFile to access the name. // Must open the QTemporaryFile to access the name.
QTemporaryFile tmpfile; QTemporaryFile tmpfile;
@ -351,27 +381,10 @@ QString dvifile::convertPDFtoPS(const QString &PDFFilename, QString *converrorms
// Use pdf2ps to do the conversion // Use pdf2ps to do the conversion
QProcess pdf2ps; QProcess pdf2ps;
pdf2ps.setProcessChannelMode(QProcess::MergedChannels); pdf2ps.setProcessChannelMode(QProcess::MergedChannels);
pdf2ps.start(QStringLiteral("pdf2ps"), QStringList() << PDFFilename << convertedFileName, QIODevice::ReadOnly | QIODevice::Text); pdf2ps.start(fullPath, QStringList() << PDFFilename << convertedFileName, QIODevice::ReadOnly | QIODevice::Text);
if (!pdf2ps.waitForStarted()) { if (!pdf2ps.waitForStarted()) {
// Indicates that conversion failed, won't try again. pdf2psNotFound(PDFFilename, converrorms);
convertedFiles[PDFFilename].clear();
if (converrorms != nullptr && !have_complainedAboutMissingPDF2PS) {
*converrorms = i18n(
"<qt><p>The external program <strong>pdf2ps</strong> could not be started. As a result, "
"the PDF-file %1 could not be converted to PostScript. Some graphic elements in your "
"document will therefore not be displayed.</p>"
"<p><b>Possible reason:</b> The program <strong>pdf2ps</strong> may not be installed "
"on your system, or cannot be found in the current search path.</p>"
"<p><b>What you can do:</b> The program <strong>pdf2ps</strong> is normally "
"contained in distributions of the ghostscript PostScript interpreter system. If "
"ghostscript is not installed on your system, you could install it now. "
"If you are sure that ghostscript is installed, try to use <strong>pdf2ps</strong> "
"from the command line to check if it really works.</p><p><em>PATH:</em> %2</p></qt>",
PDFFilename,
QString::fromLocal8Bit(qgetenv("PATH")));
have_complainedAboutMissingPDF2PS = true;
}
return QString(); return QString();
} }

@ -131,6 +131,8 @@ public:
QString convertPDFtoPS(const QString &PDFFilename, QString *converrorms = nullptr); QString convertPDFtoPS(const QString &PDFFilename, QString *converrorms = nullptr);
private: private:
void pdf2psNotFound(const QString &PDFFilename, QString *converrorms);
/** process_preamble reads the information in the preamble and /** process_preamble reads the information in the preamble and
stores it into global variables for later use. */ stores it into global variables for later use. */
void process_preamble(); void process_preamble();

@ -28,6 +28,7 @@
#include <QImage> #include <QImage>
#include <QPaintDevice> #include <QPaintDevice>
#include <QProgressBar> #include <QProgressBar>
#include <QStandardPaths>
#include <QTextStream> #include <QTextStream>
extern QPainter foreGroundPaint; extern QPainter foreGroundPaint;
@ -278,11 +279,15 @@ void dviRenderer::prescan_ParsePSHeaderSpecial(const QString &cp)
// to find it. // to find it.
if (!QFile::exists(_file)) { if (!QFile::exists(_file)) {
// Otherwise, use kpsewhich to find the eps file. // Otherwise, use kpsewhich to find the eps file.
KProcess proc; // Make sure kpsewhich is in PATH and not just in the CWD
proc << QStringLiteral("kpsewhich") << cp; static const QString fullPath = QStandardPaths::findExecutable(QStringLiteral("kpsewhich"));
proc.setOutputChannelMode(KProcess::SeparateChannels); if (!fullPath.isEmpty()) {
proc.execute(); KProcess proc;
_file = QString::fromLocal8Bit(proc.readLine().trimmed()); proc << fullPath << cp;
proc.setOutputChannelMode(KProcess::SeparateChannels);
proc.execute();
_file = QString::fromLocal8Bit(proc.readLine().trimmed());
}
} }
if (QFile::exists(_file)) if (QFile::exists(_file))

@ -16,6 +16,7 @@
#include <QFile> #include <QFile>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QProcess> #include <QProcess>
#include <QStandardPaths>
#include <QTextStream> #include <QTextStream>
//#define DEBUG_FONTENC //#define DEBUG_FONTENC
@ -31,7 +32,14 @@ fontEncoding::fontEncoding(const QString &encName)
QProcess kpsewhich; QProcess kpsewhich;
kpsewhich.setProcessChannelMode(QProcess::MergedChannels); kpsewhich.setProcessChannelMode(QProcess::MergedChannels);
kpsewhich.start(QStringLiteral("kpsewhich"), QStringList() << encName, QIODevice::ReadOnly | QIODevice::Text); // Make sure kpsewhich is in PATH and not just in the CWD
static const QString fullPath = QStandardPaths::findExecutable(QStringLiteral("kpsewhich"));
if (fullPath.isEmpty()) {
qCCritical(OkularDviDebug) << "fontEncoding::fontEncoding(...): kpsewhich is not in path." << endl;
return;
}
kpsewhich.start(fullPath, QStringList() << encName, QIODevice::ReadOnly | QIODevice::Text);
if (!kpsewhich.waitForStarted()) { if (!kpsewhich.waitForStarted()) {
qCCritical(OkularDviDebug) << "fontEncoding::fontEncoding(...): kpsewhich could not be started." << endl; qCCritical(OkularDviDebug) << "fontEncoding::fontEncoding(...): kpsewhich could not be started." << endl;

@ -15,12 +15,16 @@
#include <QFile> #include <QFile>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QProcess> #include <QProcess>
#include <QStandardPaths>
#include <QTextStream> #include <QTextStream>
//#define DEBUG_FONTMAP //#define DEBUG_FONTMAP
fontMap::fontMap() fontMap::fontMap()
{ {
// Make sure kpsewhich is in PATH and not just in the CWD
static const QString kpsewhichFullPath = QStandardPaths::findExecutable(QStringLiteral("kpsewhich"));
// Read the map file of ps2pk which will provide us with a // Read the map file of ps2pk which will provide us with a
// dictionary "TeX Font names" <-> "Name of font files, Font Names // dictionary "TeX Font names" <-> "Name of font files, Font Names
// and Encodings" (example: the font "Times-Roman" is called // and Encodings" (example: the font "Times-Roman" is called
@ -35,7 +39,7 @@ fontMap::fontMap()
// other way than to try both options one after another. We use the // other way than to try both options one after another. We use the
// teTeX 3.0 format first. // teTeX 3.0 format first.
QProcess kpsewhich; QProcess kpsewhich;
kpsewhich.start(QStringLiteral("kpsewhich"), QStringList() << QStringLiteral("--format=map") << QStringLiteral("ps2pk.map"), QIODevice::ReadOnly | QIODevice::Text); kpsewhich.start(kpsewhichFullPath, QStringList() << QStringLiteral("--format=map") << QStringLiteral("ps2pk.map"), QIODevice::ReadOnly | QIODevice::Text);
if (!kpsewhich.waitForStarted()) { if (!kpsewhich.waitForStarted()) {
qCCritical(OkularDviDebug) << "fontMap::fontMap(): kpsewhich could not be started." << endl; qCCritical(OkularDviDebug) << "fontMap::fontMap(): kpsewhich could not be started." << endl;
@ -49,7 +53,7 @@ fontMap::fontMap()
if (map_fileName.isEmpty()) { if (map_fileName.isEmpty()) {
// Map file not found? Then we try the teTeX < 3.0 way of finding // Map file not found? Then we try the teTeX < 3.0 way of finding
// the file. // the file.
kpsewhich.start(QStringLiteral("kpsewhich"), QStringList() << QStringLiteral("--format=dvips config") << QStringLiteral("ps2pk.map"), QIODevice::ReadOnly | QIODevice::Text); kpsewhich.start(kpsewhichFullPath, QStringList() << QStringLiteral("--format=dvips config") << QStringLiteral("ps2pk.map"), QIODevice::ReadOnly | QIODevice::Text);
if (!kpsewhich.waitForStarted()) { if (!kpsewhich.waitForStarted()) {
qCCritical(OkularDviDebug) << "fontMap::fontMap(): kpsewhich could not be started." << endl; qCCritical(OkularDviDebug) << "fontMap::fontMap(): kpsewhich could not be started." << endl;
return; return;

@ -15,6 +15,7 @@
#include <QApplication> #include <QApplication>
#include <QPainter> #include <QPainter>
#include <QStandardPaths>
#include <cmath> #include <cmath>
#include <math.h> #include <math.h>
@ -213,6 +214,12 @@ void fontPool::locateFonts()
void fontPool::locateFonts(bool makePK, bool locateTFMonly, bool *virtualFontsFound) void fontPool::locateFonts(bool makePK, bool locateTFMonly, bool *virtualFontsFound)
{ {
// Make sure kpsewhich is in PATH and not just in the CWD
static const QString kpsewhichFullPath = QStandardPaths::findExecutable(QStringLiteral("kpsewhich"));
if (kpsewhichFullPath.isEmpty()) {
return;
}
// Set up the kpsewhich process. If pass == 0, look for vf-fonts and // Set up the kpsewhich process. If pass == 0, look for vf-fonts and
// disable automatic font generation as vf-fonts can't be // disable automatic font generation as vf-fonts can't be
// generated. If pass == 0, enable font generation, if it was // generated. If pass == 0, enable font generation, if it was
@ -264,7 +271,7 @@ void fontPool::locateFonts(bool makePK, bool locateTFMonly, bool *virtualFontsFo
const QString kpsewhich_exe = QStringLiteral("kpsewhich"); const QString kpsewhich_exe = QStringLiteral("kpsewhich");
kpsewhichOutput += QStringLiteral("<b>") + kpsewhich_exe + QLatin1Char(' ') + kpsewhich_args.join(QStringLiteral(" ")) + QStringLiteral("</b>"); kpsewhichOutput += QStringLiteral("<b>") + kpsewhich_exe + QLatin1Char(' ') + kpsewhich_args.join(QStringLiteral(" ")) + QStringLiteral("</b>");
kpsewhich_->start(kpsewhich_exe, kpsewhich_args, QIODevice::ReadOnly | QIODevice::Text); kpsewhich_->start(kpsewhichFullPath, kpsewhich_args, QIODevice::ReadOnly | QIODevice::Text);
if (!kpsewhich_->waitForStarted()) { if (!kpsewhich_->waitForStarted()) {
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
emit error(i18n("<qt><p>There were problems running <em>kpsewhich</em>. As a result, " emit error(i18n("<qt><p>There were problems running <em>kpsewhich</em>. As a result, "

@ -24,6 +24,7 @@
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QPainter> #include <QPainter>
#include <QPixmap> #include <QPixmap>
#include <QStandardPaths>
#include <QTextStream> #include <QTextStream>
#include <QTimer> #include <QTimer>
@ -157,6 +158,13 @@ void ghostscript_interface::gs_generate_graphics_file(const quint16 page, const
return; return;
} }
// Make sure gs is in PATH and not just in the CWD
static const QString gsFullPath = QStandardPaths::findExecutable(QStringLiteral("gs"));
if (gsFullPath.isEmpty()) {
qCCritical(OkularDviDebug) << "gs is not in path" << endl;
return;
}
pageInfo *info = pageList.value(page); pageInfo *info = pageList.value(page);
// Generate a PNG-file // Generate a PNG-file
@ -216,7 +224,7 @@ void ghostscript_interface::gs_generate_graphics_file(const quint16 page, const
KProcess proc; KProcess proc;
proc.setOutputChannelMode(KProcess::SeparateChannels); proc.setOutputChannelMode(KProcess::SeparateChannels);
QStringList argus; QStringList argus;
argus << QStringLiteral("gs"); argus << gsFullPath;
argus << QStringLiteral("-dSAFER") << QStringLiteral("-dPARANOIDSAFER") << QStringLiteral("-dDELAYSAFER") << QStringLiteral("-dNOPAUSE") << QStringLiteral("-dBATCH"); argus << QStringLiteral("-dSAFER") << QStringLiteral("-dPARANOIDSAFER") << QStringLiteral("-dDELAYSAFER") << QStringLiteral("-dNOPAUSE") << QStringLiteral("-dBATCH");
argus << QStringLiteral("-sDEVICE=%1").arg(*gsDevice); argus << QStringLiteral("-sDEVICE=%1").arg(*gsDevice);
argus << QStringLiteral("-sOutputFile=%1").arg(filename); argus << QStringLiteral("-sOutputFile=%1").arg(filename);
@ -328,8 +336,14 @@ QString ghostscript_interface::locateEPSfile(const QString &filename, const QUrl
} }
// Otherwise, use kpsewhich to find the eps file. // Otherwise, use kpsewhich to find the eps file.
// Make sure kpsewhich is in PATH and not just in the CWD
static const QString fullPath = QStandardPaths::findExecutable(QStringLiteral("kpsewhich"));
if (fullPath.isEmpty()) {
return {};
}
KProcess proc; KProcess proc;
proc << QStringLiteral("kpsewhich") << filename; proc << fullPath << filename;
proc.execute(); proc.execute();
return QString::fromLocal8Bit(proc.readLine().trimmed()); return QString::fromLocal8Bit(proc.readLine().trimmed());
} }

Loading…
Cancel
Save