Chandra
view release on metacpan or search on metacpan
include/webview-edge.c view on Meta::CPAN
/* WebMessageHandler */
static HRESULT STDMETHODCALLTYPE wmh_QueryInterface(ICoreWebView2WebMessageReceivedEventHandler *This, REFIID riid, void **ppv) {
(void)riid;
*ppv = This;
This->lpVtbl->AddRef(This);
return S_OK;
}
static ULONG STDMETHODCALLTYPE wmh_AddRef(ICoreWebView2WebMessageReceivedEventHandler *This) {
WebMessageHandler *h = (WebMessageHandler *)This;
return InterlockedIncrement(&h->ref);
}
static ULONG STDMETHODCALLTYPE wmh_Release(ICoreWebView2WebMessageReceivedEventHandler *This) {
WebMessageHandler *h = (WebMessageHandler *)This;
LONG ref = InterlockedDecrement(&h->ref);
if (ref == 0) {
GlobalFree(h);
}
return ref;
}
static HRESULT STDMETHODCALLTYPE wmh_Invoke(
ICoreWebView2WebMessageReceivedEventHandler *This,
ICoreWebView2 *sender,
ICoreWebView2WebMessageReceivedEventArgs *args) {
include/webview-edge.c view on Meta::CPAN
/* EnvironmentHandler */
static HRESULT STDMETHODCALLTYPE eh_QueryInterface(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler *This, REFIID riid, void **ppv) {
(void)riid;
*ppv = This;
This->lpVtbl->AddRef(This);
return S_OK;
}
static ULONG STDMETHODCALLTYPE eh_AddRef(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler *This) {
EnvironmentHandler *h = (EnvironmentHandler *)This;
return InterlockedIncrement(&h->ref);
}
static ULONG STDMETHODCALLTYPE eh_Release(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler *This) {
EnvironmentHandler *h = (EnvironmentHandler *)This;
LONG ref = InterlockedDecrement(&h->ref);
if (ref == 0) {
GlobalFree(h);
}
return ref;
}
/* Forward declaration for controller creation */
static void webview2_create_controller(struct webview *w);
static HRESULT STDMETHODCALLTYPE eh_Invoke(
include/webview-edge.c view on Meta::CPAN
/* ControllerHandler */
static HRESULT STDMETHODCALLTYPE ch_QueryInterface(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler *This, REFIID riid, void **ppv) {
(void)riid;
*ppv = This;
This->lpVtbl->AddRef(This);
return S_OK;
}
static ULONG STDMETHODCALLTYPE ch_AddRef(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler *This) {
ControllerHandler *h = (ControllerHandler *)This;
return InterlockedIncrement(&h->ref);
}
static ULONG STDMETHODCALLTYPE ch_Release(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler *This) {
ControllerHandler *h = (ControllerHandler *)This;
LONG ref = InterlockedDecrement(&h->ref);
if (ref == 0) {
GlobalFree(h);
}
return ref;
}
static HRESULT STDMETHODCALLTYPE ch_Invoke(
ICoreWebView2CreateCoreWebView2ControllerCompletedHandler *This,
HRESULT result,
ICoreWebView2Controller *controller) {
include/webview-gtk.c view on Meta::CPAN
}
WEBVIEW_API void webview_dispatch(struct webview *w, webview_dispatch_fn fn,
void *arg) {
struct webview_dispatch_arg *context =
(struct webview_dispatch_arg *)g_new(struct webview_dispatch_arg, 1);
context->w = w;
context->arg = arg;
context->fn = fn;
g_async_queue_lock(w->priv.queue);
g_async_queue_push_unlocked(w->priv.queue, context);
if (g_async_queue_length_unlocked(w->priv.queue) == 1) {
gdk_threads_add_idle(webview_dispatch_wrapper, w);
}
g_async_queue_unlock(w->priv.queue);
}
WEBVIEW_API void webview_terminate(struct webview *w) {
w->priv.should_exit = 1;
}
WEBVIEW_API void webview_exit(struct webview *w) { (void)w; }
include/webview-win32.c view on Meta::CPAN
*ppv = &s->ui_handler;
} else {
return E_NOINTERFACE;
}
site_AddRef(This);
return S_OK;
}
static ULONG STDMETHODCALLTYPE site_AddRef(IOleClientSite *This) {
WebviewSite *s = (WebviewSite *)This;
return InterlockedIncrement(&s->ref);
}
static ULONG STDMETHODCALLTYPE site_Release(IOleClientSite *This) {
WebviewSite *s = (WebviewSite *)This;
LONG ref = InterlockedDecrement(&s->ref);
if (ref == 0) {
GlobalFree(s);
}
return ref;
}
static WebviewSite *create_site(struct webview *w, HWND hwnd) {
WebviewSite *s = (WebviewSite *)GlobalAlloc(GPTR, sizeof(WebviewSite));
if (!s) return NULL;
s->client_site.lpVtbl = &client_site_vtbl;
lib/Chandra/Assets.pm view on Meta::CPAN
# Read asset content
my $content = $assets->read('css/style.css');
# Check existence
if ($assets->exists('images/logo.png')) { ... }
=head1 DESCRIPTION
Serve local CSS, JS, images, and fonts from a directory via custom protocol.
Uses L<Chandra::Protocol> internally to register the asset scheme. Path
traversal attacks are blocked.
=head1 METHODS
=head2 new
my $assets = Chandra::Assets->new(
root => 'assets/', # required
prefix => 'app', # default: 'asset'
app => $app, # optional, can pass to mount() instead
);
t/45_assets.t view on Meta::CPAN
ok($a->exists('index.html'), 'exists: html file');
ok(!$a->exists('nonexistent.txt'), 'exists: missing file');
}
# ---- path traversal protection ----
{
my $a = Chandra::Assets->new(root => $dir);
eval { $a->read('../etc/passwd') };
like($@, qr/traversal/, 'path traversal with .. blocked');
eval { $a->read('css/../../etc/passwd') };
like($@, qr/traversal/, 'path traversal mid-path blocked');
ok(!$a->exists('../etc/passwd'), 'exists returns false for traversal');
}
# ---- list ----
{
my $a = Chandra::Assets->new(root => $dir);
my @all = $a->list;
ok(scalar @all > 0, 'list returns entries');
t/46_assets_edge.t view on Meta::CPAN
my @bad_paths = (
'../etc/passwd',
'../../root/.ssh/id_rsa',
'sub/../../etc/shadow',
'sub/../../../outside',
);
for my $bad (@bad_paths) {
eval { $a->read($bad) };
like($@, qr/traversal/i, "blocked: $bad");
}
}
# ---- Backslash rejection ----
{
my $a = Chandra::Assets->new(root => $dir);
eval { $a->read('sub\\nested.js') };
like($@, qr/traversal/i, 'backslash path rejected');
( run in 1.320 second using v1.01-cache-2.11-cpan-39bf76dae61 )