Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/CairoContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

QoreCairoContext::QoreCairoContext(QoreCairoSurface* surface, ExceptionSink* xsink) : surface_ref(surface) {
assert(surface);
surface->ref();
// NOTE: caller (QPP-generated code via HARD_QORE_VALUE_OBJ_DATA) already holds a reference
// from getReferencedPrivateData(); we take ownership of that reference here
cr = cairo_create(surface->getSurface());
checkStatus(xsink);
}
Expand Down
28 changes: 28 additions & 0 deletions src/CairoSurface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ QoreCairoSurface::QoreCairoSurface(const std::string& path, double width, double
xsink->raiseException("CAIRO-ERROR", "surface dimensions must be positive (%.2f x %.2f)", width, height);
return;
}
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_WRITE | QSEC_CREATE, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "SVG surface create")) {
return;
}
surface = cairo_svg_surface_create(path.c_str(), width, height);
checkStatus(xsink);
}
Expand All @@ -59,6 +66,13 @@ QoreCairoSurface::QoreCairoSurface(const std::string& path, double width, double
xsink->raiseException("CAIRO-ERROR", "surface dimensions must be positive (%.2f x %.2f)", width, height);
return;
}
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_WRITE | QSEC_CREATE, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "PostScript surface create")) {
return;
}
surface = cairo_ps_surface_create(path.c_str(), width, height);
checkStatus(xsink);
}
Expand Down Expand Up @@ -87,6 +101,13 @@ QoreCairoSurface::QoreCairoSurface(int width, int height, cairo_format_t format,

// Image surface from PNG file
QoreCairoSurface::QoreCairoSurface(const std::string& path, ExceptionSink* xsink) : type(CST_IMAGE) {
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_READ, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "PNG file load")) {
return;
}
surface = cairo_image_surface_create_from_png(path.c_str());
cairo_status_t status = cairo_surface_status(surface);
if (status != CAIRO_STATUS_SUCCESS) {
Expand Down Expand Up @@ -172,6 +193,13 @@ void QoreCairoSurface::writeToPng(const std::string& path, ExceptionSink* xsink)
xsink->raiseException("CAIRO-ERROR", "writeToPng is only available for image and recording surfaces");
return;
}
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_WRITE | QSEC_CREATE, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "PNG file write")) {
return;
}
cairo_status_t status = cairo_surface_write_to_png(surface, path.c_str());
if (status != CAIRO_STATUS_SUCCESS) {
xsink->raiseException("CAIRO-ERROR", "failed to write PNG to '%s': %s",
Expand Down
7 changes: 7 additions & 0 deletions src/CairoSvgReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
#ifdef HAVE_RSVG

QoreCairoSvgReader::QoreCairoSvgReader(const std::string& path, ExceptionSink* xsink) {
QoreSandboxManagerHelper smh;
if (smh && !smh->checkFilesystemAccess(path.c_str(), QSEC_READ, xsink)) {
return;
}
if (qore_check_io_interrupt(xsink, "SVG file load")) {
return;
}
GError* error = nullptr;
GFile* file = g_file_new_for_path(path.c_str());
handle = rsvg_handle_new_from_gfile_sync(file, RSVG_HANDLE_FLAGS_NONE, nullptr, &error);
Expand Down
2 changes: 2 additions & 0 deletions src/QC_CairoContext.qpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,15 @@ nothing CairoContext::setSourceRgba(float r, float g, float b, float a) {
@param y Y offset for the surface origin
*/
nothing CairoContext::setSourceSurface(CairoSurface[QoreCairoSurface] surface, float x, float y) {
ReferenceHolder<QoreCairoSurface> holder(surface, xsink);
ctx->setSourceSurface(surface, x, y, xsink);
}

//! Sets a pattern as the source
/** @param pattern the source pattern
*/
nothing CairoContext::setSource(CairoPattern[QoreCairoPattern] pattern) {
ReferenceHolder<QoreCairoPattern> holder(pattern, xsink);
ctx->setSource(pattern->getPattern(), xsink);
}

Expand Down
8 changes: 8 additions & 0 deletions src/QC_CairoPattern.qpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@
*/
qclass CairoPattern [arg=QoreCairoPattern* pattern; ns=Qore::Cairo];

//! Private constructor - use static factory methods instead
/** @throw CAIRO-ERROR always; CairoPattern objects must be created using static factory methods
*/
private CairoPattern::constructor() {
xsink->raiseException("CAIRO-ERROR", "CairoPattern cannot be constructed directly; use static factory methods");
}

//! Creates a linear gradient pattern
/** @param x0 start point X
@param y0 start point Y
Expand Down Expand Up @@ -102,6 +109,7 @@ static CairoPattern CairoPattern::createRgba(float r, float g, float b, float a)
/** @param surface the source surface
*/
static CairoPattern CairoPattern::createForSurface(CairoSurface[QoreCairoSurface] surface) {
ReferenceHolder<QoreCairoSurface> surface_holder(surface, xsink);
ReferenceHolder<QoreCairoPattern> holder(new QoreCairoPattern(surface, xsink), xsink);
if (*xsink) {
return QoreValue();
Expand Down
7 changes: 7 additions & 0 deletions src/QC_CairoSurface.qpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ hashdecl Qore::Cairo::CairoTextExtents {
*/
qclass CairoSurface [arg=QoreCairoSurface* surface; ns=Qore::Cairo];

//! Private constructor - use static factory methods instead
/** @throw CAIRO-ERROR always; CairoSurface objects must be created using static factory methods
*/
private CairoSurface::constructor() {
xsink->raiseException("CAIRO-ERROR", "CairoSurface cannot be constructed directly; use static factory methods");
}

//! Creates an SVG surface writing to a file
/** @param path output file path
@param width surface width in points
Expand Down
1 change: 1 addition & 0 deletions src/QC_CairoSvgReader.qpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ hash<auto> CairoSvgReader::getDimensions() {
/** @param ctx the target drawing context
*/
nothing CairoSvgReader::renderTo(CairoContext[QoreCairoContext] ctx) {
ReferenceHolder<QoreCairoContext> holder(ctx, xsink);
reader->renderTo(ctx, xsink);
}

Expand Down
1 change: 1 addition & 0 deletions src/cairo-module.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define QORE_CAIRO_MODULE_H

#include <qore/Qore.h>
#include <qore/QoreSandboxManager.h>

extern const TypedHashDecl* hashdeclCairoSurfaceInfo;
extern const TypedHashDecl* hashdeclCairoMatrix;
Expand Down