Use native candidate actions and harden frontend resource loading
This commit is contained in:
1 parent
99fe8f589f
commit
d8e780dfa1
18 files changed
+1083
-227
No files matched your search
@@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "fcitx-utils/log.h"
|
||||
#include "../src/imageloader.h"
|
||||
|
||||
using namespace fcitx::m3ui;
|
||||
|
||||
int main() {
|
||||
FCITX_ASSERT(!loadRasterImage({}));
|
||||
FCITX_ASSERT(!loadSvgImage({}));
|
||||
FCITX_ASSERT(!loadRasterImage({'b', 'a', 'd'}));
|
||||
FCITX_ASSERT(!loadSvgImage({'b', 'a', 'd'}));
|
||||
|
||||
// Valid PNG bytes exercise the real incremental decoder, regardless of
|
||||
// extension. The reference must remain valid after loader destruction.
|
||||
LoadedSurface surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 16, 16));
|
||||
std::vector<uint8_t> png;
|
||||
FCITX_ASSERT(cairo_surface_write_to_png_stream(
|
||||
surface.get(),
|
||||
+[](void *data, const unsigned char *bytes, unsigned int length) {
|
||||
auto &out = *static_cast<std::vector<uint8_t> *>(data);
|
||||
out.insert(out.end(), bytes, bytes + length);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
},
|
||||
&png) == CAIRO_STATUS_SUCCESS);
|
||||
auto image = loadRasterImage(png);
|
||||
FCITX_ASSERT(image);
|
||||
FCITX_ASSERT(gdk_pixbuf_get_width(image.get()) == 16);
|
||||
FCITX_ASSERT(gdk_pixbuf_get_height(image.get()) == 16);
|
||||
png[16] = 255; // Huge IHDR, rejected before entering libpng.
|
||||
FCITX_ASSERT(!loadRasterImage(png));
|
||||
png.resize(23);
|
||||
FCITX_ASSERT(!loadRasterImage(png));
|
||||
|
||||
// A real non-PNG image exercises size-prepared rather than PNG preflight.
|
||||
gchar *bmpData = nullptr;
|
||||
gsize bmpSize = 0;
|
||||
FCITX_ASSERT(gdk_pixbuf_save_to_buffer(image.get(), &bmpData, &bmpSize,
|
||||
"bmp", nullptr, nullptr));
|
||||
std::vector<uint8_t> bmp(bmpData, bmpData + bmpSize);
|
||||
g_free(bmpData);
|
||||
FCITX_ASSERT(loadRasterImage(bmp));
|
||||
// BMP BITMAPINFOHEADER width is little-endian at byte 18.
|
||||
FCITX_ASSERT(bmp.size() > 26 && bmp[14] >= 40);
|
||||
bmp[18] = 1;
|
||||
bmp[19] = 32; // 8193 pixels wide
|
||||
bmp[20] = bmp[21] = 0;
|
||||
FCITX_ASSERT(!loadRasterImage(bmp));
|
||||
|
||||
auto svg = [](const std::string &text) {
|
||||
return loadSvgImage(std::vector<uint8_t>(text.begin(), text.end()));
|
||||
};
|
||||
auto rendered = svg("<svg xmlns='http://www.w3.org/2000/svg' width='16' "
|
||||
"height='16'><rect width='16' height='16' "
|
||||
"fill='red'/></svg>");
|
||||
FCITX_ASSERT(rendered);
|
||||
FCITX_ASSERT(cairo_surface_get_type(rendered.get()) == CAIRO_SURFACE_TYPE_IMAGE);
|
||||
FCITX_ASSERT(cairo_image_surface_get_width(rendered.get()) == 16);
|
||||
FCITX_ASSERT(cairo_image_surface_get_height(rendered.get()) == 16);
|
||||
cairo_surface_flush(rendered.get());
|
||||
const auto *pixel = reinterpret_cast<const uint32_t *>(
|
||||
cairo_image_surface_get_data(rendered.get()));
|
||||
FCITX_ASSERT(pixel[0] == 0xffff0000); // Native-endian Cairo ARGB32.
|
||||
FCITX_ASSERT(!svg("<svg xmlns='http://www.w3.org/2000/svg' "
|
||||
"width='1e30' height='16'/>"));
|
||||
FCITX_ASSERT(!svg("<svg xmlns='http://www.w3.org/2000/svg' "
|
||||
"width='8192' height='8192'/>"));
|
||||
FCITX_ASSERT(!svg("<svg xmlns='http://www.w3.org/2000/svg' "
|
||||
"width='0' height='16'/>"));
|
||||
FCITX_ASSERT(!svg("<svg xmlns='http://www.w3.org/2000/svg'"));
|
||||
|
||||
std::vector<uint8_t> oversized(16 * 1024 * 1024 + 1);
|
||||
FCITX_ASSERT(!loadRasterImage(oversized));
|
||||
FCITX_ASSERT(!loadSvgImage(oversized));
|
||||
}
|
||||
Reference in new issue
Block a user