@marimo-team/islands 0.23.2-dev39 → 0.23.2-dev40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chat-ui-CxiINNTE.js → chat-ui-D3oNzud1.js} +2753 -2753
- package/dist/main.js +158 -155
- package/dist/{process-output-CM8yijAP.js → process-output-BWEipdFR.js} +106 -105
- package/package.json +1 -1
- package/src/plugins/core/__test__/trusted-url.test.ts +45 -1
- package/src/plugins/core/trusted-url.ts +27 -2
|
@@ -33,7 +33,7 @@ import { a as parser, i as pythonLanguage, n as localCompletionSource, r as pyth
|
|
|
33
33
|
import { n as stexMath } from "./stex-Ze8D4R_5.js";
|
|
34
34
|
import { t as purify } from "./purify.es-ukiMXY-F.js";
|
|
35
35
|
import { t as useAsyncData } from "./useAsyncData-B1v_9k4L.js";
|
|
36
|
-
let
|
|
36
|
+
let cellErrorsAtom, useRequestClient, MarimoIncomingMessageEvent, Wrench, createVariableInfoElement, DotFilledIcon, Eye, jotaiJsonStorage, contextToXml, selectAtom, displayCellName, AccordionContent, Item, Checkbox, Accordion, Content2$1, normalizeName, BorderAllIcon, LoaderCircle, DeferredRequestRegistry, base64ToDataView, Braces, getDataTypeColor, PinRightIcon, Columns2, PluralWord, ChatBubbleIcon, Layers, generateUUID, extractBase64FromDataURL, dataSourceConnectionsAtom, base64ToUint8Array, esm_default, require_client, CheckIcon, Info, useChromeActions, MarimoValueReadyEvent, Table2, Paths, MarimoValueUpdateEvent, PaintRoller, moveToEndOfEditor, AccordionItem, Root2$2, customPythonLanguageSupport, createInputEvent, NotebookPen, goToCellLine, hasRunAnyCellAtom, requestClientAtom, ChevronDownIcon, File, repl, Sections, atomWithStorage, getCellDomProps, AIContextRegistry, Close$1, isInternalCellName, deserializeBlob, CircleX, PluralWords, PinLeftIcon, Database, variablesAtom, base64ToDataURL, CircleAlert, DATA_TYPE_ICON, safeExtractSetUIElementMessageBuffers, convertStatsName, isDataURLString, getTableType, renderHTML, getRequestClient, useExpandedConsoleOutput, RANDOM_ID_ATTR, outputIsStale, toPng$1, NotebookScopedLocalStorage, numColumnsAtom, getDatasourceContext, jsonToTSV, sanitizeHtml, useCellFocusActions, parseAttrValue, useCellIds, Spinner, CellOutputId, AnsiUp, isUninstantiated, createActions$1, Popover, HTMLCellId, getInitialAppMode, isOutputEmpty, OBJECT_ID_ATTR, outputIsLoading, PopoverTrigger, findCellId, viewStateAtom, PythonIcon, getTracebackInfo, notebookOutline, MarimoValueInputEvent, Trash2, PathBuilder, AccordionTrigger, Trigger2, MarkdownLanguageAdapter, useLastFocusedCellId, parseDataset, useCellNames, PopoverContent, UIElementId, kioskModeAtom, blobToString, elementContainsMarimoCellFile, getCellNames, MarkdownRenderer, ZodLocalStorage, reducer$1, PopoverClose, SCRATCH_CELL_ID, initialModeAtom, dataViewToBase64, import_lib$1, allTablesAtom, filesToBase64, extractAllTracebackInfo, notebookAtom, LazyAnyLanguageCodeMirror, filenameAtom, useCellActions, processOutput, singleFacet, getCellEditorView, maybeAddAltairImport, parseInitialValue, createCell, useExpandedOutput, jsonParseWithSpecialChar, isErrorMime, AIContextProvider, Anchor2, getValidName, Boosts, atomWithReducer, DATA_CELL_ID, DatasourceContextProvider, jsonToMarkdown, headingToIdentifier, ChevronRightIcon, FileText, adaptForLocalStorage;
|
|
37
37
|
let __tla = Promise.all([
|
|
38
38
|
(() => {
|
|
39
39
|
try {
|
|
@@ -26747,7 +26747,7 @@ ${n.sqlString}
|
|
|
26747
26747
|
}), t[4] = r, t[5] = a, t[6] = o, t[7] = s) : s = t[7], s;
|
|
26748
26748
|
};
|
|
26749
26749
|
require_compiler_runtime();
|
|
26750
|
-
|
|
26750
|
+
hasRunAnyCellAtom = atom(false);
|
|
26751
26751
|
var sanitizeHtmlAtom = atom((e) => {
|
|
26752
26752
|
let t = e(hasRunAnyCellAtom), n = e(autoInstantiateAtom);
|
|
26753
26753
|
if (t || n) return false;
|
|
@@ -28424,159 +28424,160 @@ ${t}
|
|
|
28424
28424
|
};
|
|
28425
28425
|
});
|
|
28426
28426
|
export {
|
|
28427
|
-
|
|
28428
|
-
|
|
28427
|
+
cellErrorsAtom as $,
|
|
28428
|
+
useRequestClient as $t,
|
|
28429
28429
|
MarimoIncomingMessageEvent as A,
|
|
28430
|
-
|
|
28431
|
-
|
|
28430
|
+
Wrench as An,
|
|
28431
|
+
createVariableInfoElement as At,
|
|
28432
28432
|
DotFilledIcon as B,
|
|
28433
|
-
|
|
28434
|
-
|
|
28433
|
+
Eye as Bn,
|
|
28434
|
+
jotaiJsonStorage as Bt,
|
|
28435
28435
|
contextToXml as C,
|
|
28436
|
-
|
|
28437
|
-
|
|
28436
|
+
selectAtom as Cn,
|
|
28437
|
+
displayCellName as Ct,
|
|
28438
28438
|
AccordionContent as D,
|
|
28439
|
-
|
|
28440
|
-
|
|
28439
|
+
Item as Dn,
|
|
28440
|
+
Checkbox as Dt,
|
|
28441
28441
|
Accordion as E,
|
|
28442
|
-
|
|
28443
|
-
|
|
28442
|
+
Content2$1 as En,
|
|
28443
|
+
normalizeName as Et,
|
|
28444
28444
|
BorderAllIcon as F,
|
|
28445
|
-
|
|
28446
|
-
|
|
28445
|
+
LoaderCircle as Fn,
|
|
28446
|
+
DeferredRequestRegistry as Ft,
|
|
28447
28447
|
base64ToDataView as G,
|
|
28448
|
-
|
|
28449
|
-
|
|
28448
|
+
Braces as Gn,
|
|
28449
|
+
getDataTypeColor as Gt,
|
|
28450
28450
|
PinRightIcon as H,
|
|
28451
|
-
|
|
28452
|
-
|
|
28451
|
+
Columns2 as Hn,
|
|
28452
|
+
PluralWord as Ht,
|
|
28453
28453
|
ChatBubbleIcon as I,
|
|
28454
|
-
|
|
28455
|
-
|
|
28454
|
+
Layers as In,
|
|
28455
|
+
generateUUID as It,
|
|
28456
28456
|
extractBase64FromDataURL as J,
|
|
28457
|
-
|
|
28457
|
+
dataSourceConnectionsAtom as Jt,
|
|
28458
28458
|
base64ToUint8Array as K,
|
|
28459
|
-
|
|
28460
|
-
|
|
28459
|
+
esm_default as Kn,
|
|
28460
|
+
require_client as Kt,
|
|
28461
28461
|
CheckIcon as L,
|
|
28462
|
-
|
|
28463
|
-
|
|
28462
|
+
Info as Ln,
|
|
28463
|
+
useChromeActions as Lt,
|
|
28464
28464
|
MarimoValueReadyEvent as M,
|
|
28465
|
-
|
|
28466
|
-
|
|
28465
|
+
Table2 as Mn,
|
|
28466
|
+
Paths as Mt,
|
|
28467
28467
|
MarimoValueUpdateEvent as N,
|
|
28468
|
-
|
|
28469
|
-
|
|
28468
|
+
PaintRoller as Nn,
|
|
28469
|
+
moveToEndOfEditor as Nt,
|
|
28470
28470
|
AccordionItem as O,
|
|
28471
|
-
|
|
28472
|
-
|
|
28471
|
+
Root2$2 as On,
|
|
28472
|
+
customPythonLanguageSupport as Ot,
|
|
28473
28473
|
createInputEvent as P,
|
|
28474
|
-
|
|
28475
|
-
|
|
28476
|
-
|
|
28477
|
-
|
|
28474
|
+
NotebookPen as Pn,
|
|
28475
|
+
goToCellLine as Pt,
|
|
28476
|
+
hasRunAnyCellAtom as Q,
|
|
28477
|
+
requestClientAtom as Qt,
|
|
28478
28478
|
ChevronDownIcon as R,
|
|
28479
|
-
|
|
28480
|
-
|
|
28479
|
+
File as Rn,
|
|
28480
|
+
repl as Rt,
|
|
28481
28481
|
Sections as S,
|
|
28482
|
-
|
|
28483
|
-
|
|
28482
|
+
atomWithStorage as Sn,
|
|
28483
|
+
getCellDomProps as St,
|
|
28484
28484
|
AIContextRegistry as T,
|
|
28485
|
-
|
|
28486
|
-
|
|
28485
|
+
Close$1 as Tn,
|
|
28486
|
+
isInternalCellName as Tt,
|
|
28487
28487
|
deserializeBlob as U,
|
|
28488
|
-
|
|
28489
|
-
|
|
28488
|
+
CircleX as Un,
|
|
28489
|
+
PluralWords as Ut,
|
|
28490
28490
|
PinLeftIcon as V,
|
|
28491
|
-
|
|
28492
|
-
|
|
28491
|
+
Database as Vn,
|
|
28492
|
+
variablesAtom as Vt,
|
|
28493
28493
|
base64ToDataURL as W,
|
|
28494
|
-
|
|
28495
|
-
|
|
28494
|
+
CircleAlert as Wn,
|
|
28495
|
+
DATA_TYPE_ICON as Wt,
|
|
28496
28496
|
safeExtractSetUIElementMessageBuffers as X,
|
|
28497
|
-
|
|
28497
|
+
convertStatsName as Xt,
|
|
28498
28498
|
isDataURLString as Y,
|
|
28499
|
-
|
|
28499
|
+
getTableType as Yt,
|
|
28500
28500
|
renderHTML as Z,
|
|
28501
|
-
|
|
28501
|
+
getRequestClient as Zt,
|
|
28502
28502
|
useExpandedConsoleOutput as _,
|
|
28503
28503
|
__tla,
|
|
28504
|
-
|
|
28505
|
-
|
|
28504
|
+
RANDOM_ID_ATTR as _n,
|
|
28505
|
+
outputIsStale as _t,
|
|
28506
28506
|
toPng$1 as a,
|
|
28507
|
-
|
|
28508
|
-
|
|
28507
|
+
NotebookScopedLocalStorage as an,
|
|
28508
|
+
numColumnsAtom as at,
|
|
28509
28509
|
getDatasourceContext as b,
|
|
28510
|
-
|
|
28511
|
-
|
|
28510
|
+
jsonToTSV as bn,
|
|
28511
|
+
sanitizeHtml as bt,
|
|
28512
28512
|
useCellFocusActions as c,
|
|
28513
|
-
|
|
28514
|
-
|
|
28513
|
+
parseAttrValue as cn,
|
|
28514
|
+
useCellIds as ct,
|
|
28515
28515
|
Spinner as d,
|
|
28516
|
-
|
|
28517
|
-
|
|
28518
|
-
|
|
28519
|
-
|
|
28516
|
+
CellOutputId as dn,
|
|
28517
|
+
AnsiUp as dt,
|
|
28518
|
+
isUninstantiated as en,
|
|
28519
|
+
createActions$1 as et,
|
|
28520
28520
|
Popover as f,
|
|
28521
|
-
|
|
28522
|
-
|
|
28521
|
+
HTMLCellId as fn,
|
|
28522
|
+
getInitialAppMode as ft,
|
|
28523
28523
|
isOutputEmpty as g,
|
|
28524
|
-
|
|
28525
|
-
|
|
28524
|
+
OBJECT_ID_ATTR as gn,
|
|
28525
|
+
outputIsLoading as gt,
|
|
28526
28526
|
PopoverTrigger as h,
|
|
28527
|
-
|
|
28528
|
-
|
|
28527
|
+
findCellId as hn,
|
|
28528
|
+
viewStateAtom as ht,
|
|
28529
28529
|
PythonIcon as i,
|
|
28530
|
-
|
|
28531
|
-
|
|
28530
|
+
getTracebackInfo as in,
|
|
28531
|
+
notebookOutline as it,
|
|
28532
28532
|
MarimoValueInputEvent as j,
|
|
28533
|
-
|
|
28534
|
-
|
|
28533
|
+
Trash2 as jn,
|
|
28534
|
+
PathBuilder as jt,
|
|
28535
28535
|
AccordionTrigger as k,
|
|
28536
|
-
|
|
28537
|
-
|
|
28536
|
+
Trigger2 as kn,
|
|
28537
|
+
MarkdownLanguageAdapter as kt,
|
|
28538
28538
|
useLastFocusedCellId as l,
|
|
28539
|
-
|
|
28540
|
-
|
|
28539
|
+
parseDataset as ln,
|
|
28540
|
+
useCellNames as lt,
|
|
28541
28541
|
PopoverContent as m,
|
|
28542
|
-
|
|
28543
|
-
|
|
28542
|
+
UIElementId as mn,
|
|
28543
|
+
kioskModeAtom as mt,
|
|
28544
28544
|
blobToString as n,
|
|
28545
|
-
|
|
28546
|
-
|
|
28545
|
+
elementContainsMarimoCellFile as nn,
|
|
28546
|
+
getCellNames as nt,
|
|
28547
28547
|
MarkdownRenderer as o,
|
|
28548
|
-
|
|
28549
|
-
|
|
28548
|
+
ZodLocalStorage as on,
|
|
28549
|
+
reducer$1 as ot,
|
|
28550
28550
|
PopoverClose as p,
|
|
28551
|
-
|
|
28552
|
-
|
|
28551
|
+
SCRATCH_CELL_ID as pn,
|
|
28552
|
+
initialModeAtom as pt,
|
|
28553
28553
|
dataViewToBase64 as q,
|
|
28554
|
-
|
|
28554
|
+
import_lib$1 as qn,
|
|
28555
|
+
allTablesAtom as qt,
|
|
28555
28556
|
filesToBase64 as r,
|
|
28556
|
-
|
|
28557
|
-
|
|
28557
|
+
extractAllTracebackInfo as rn,
|
|
28558
|
+
notebookAtom as rt,
|
|
28558
28559
|
LazyAnyLanguageCodeMirror as s,
|
|
28559
|
-
|
|
28560
|
-
|
|
28560
|
+
filenameAtom as sn,
|
|
28561
|
+
useCellActions as st,
|
|
28561
28562
|
processOutput as t,
|
|
28562
|
-
|
|
28563
|
-
|
|
28563
|
+
singleFacet as tn,
|
|
28564
|
+
getCellEditorView as tt,
|
|
28564
28565
|
maybeAddAltairImport as u,
|
|
28565
|
-
|
|
28566
|
-
|
|
28566
|
+
parseInitialValue as un,
|
|
28567
|
+
createCell as ut,
|
|
28567
28568
|
useExpandedOutput as v,
|
|
28568
|
-
|
|
28569
|
-
|
|
28569
|
+
jsonParseWithSpecialChar as vn,
|
|
28570
|
+
isErrorMime as vt,
|
|
28570
28571
|
AIContextProvider as w,
|
|
28571
|
-
|
|
28572
|
-
|
|
28572
|
+
Anchor2 as wn,
|
|
28573
|
+
getValidName as wt,
|
|
28573
28574
|
Boosts as x,
|
|
28574
|
-
|
|
28575
|
-
|
|
28575
|
+
atomWithReducer as xn,
|
|
28576
|
+
DATA_CELL_ID as xt,
|
|
28576
28577
|
DatasourceContextProvider as y,
|
|
28577
|
-
|
|
28578
|
-
|
|
28578
|
+
jsonToMarkdown as yn,
|
|
28579
|
+
headingToIdentifier as yt,
|
|
28579
28580
|
ChevronRightIcon as z,
|
|
28580
|
-
|
|
28581
|
-
|
|
28581
|
+
FileText as zn,
|
|
28582
|
+
adaptForLocalStorage as zt
|
|
28582
28583
|
};
|
package/package.json
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
3
|
+
import { hasRunAnyCellAtom } from "@/components/editor/cell/useRunCells";
|
|
4
|
+
import { store } from "@/core/state/jotai";
|
|
3
5
|
import { isTrustedVirtualFileUrl } from "../trusted-url";
|
|
4
6
|
|
|
5
7
|
describe("isTrustedVirtualFileUrl", () => {
|
|
@@ -45,4 +47,46 @@ describe("isTrustedVirtualFileUrl", () => {
|
|
|
45
47
|
expect(isTrustedVirtualFileUrl(42)).toBe(false);
|
|
46
48
|
expect(isTrustedVirtualFileUrl({})).toBe(false);
|
|
47
49
|
});
|
|
50
|
+
|
|
51
|
+
describe("data URL exemption", () => {
|
|
52
|
+
let previousHasRunAnyCell: boolean;
|
|
53
|
+
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
previousHasRunAnyCell = store.get(hasRunAnyCellAtom);
|
|
56
|
+
store.set(hasRunAnyCellAtom, true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
store.set(hasRunAnyCellAtom, previousHasRunAnyCell);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it.each([
|
|
64
|
+
"data:text/javascript;base64,ZXhwb3J0IGRlZmF1bHQge30=",
|
|
65
|
+
"data:application/javascript;base64,ZXhwb3J0IGRlZmF1bHQge30=",
|
|
66
|
+
"data:text/css;base64,Ym9keXt9",
|
|
67
|
+
])("accepts safe data URL %s after a cell has run", (url) => {
|
|
68
|
+
expect(isTrustedVirtualFileUrl(url)).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it.each([
|
|
72
|
+
// Non-base64 data URLs are refused
|
|
73
|
+
"data:text/javascript,alert(1)",
|
|
74
|
+
"data:text/javascript;charset=utf-8,alert(1)",
|
|
75
|
+
// HTML / SVG / arbitrary types are refused
|
|
76
|
+
"data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==",
|
|
77
|
+
"data:image/svg+xml;base64,PHN2Zy8+",
|
|
78
|
+
"data:application/octet-stream;base64,AAA=",
|
|
79
|
+
])("still rejects unsafe data URL %s", (url) => {
|
|
80
|
+
expect(isTrustedVirtualFileUrl(url)).toBe(false);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("rejects data URL when no cell has been run", () => {
|
|
84
|
+
store.set(hasRunAnyCellAtom, false);
|
|
85
|
+
expect(
|
|
86
|
+
isTrustedVirtualFileUrl(
|
|
87
|
+
"data:text/javascript;base64,ZXhwb3J0IGRlZmF1bHQge30=",
|
|
88
|
+
),
|
|
89
|
+
).toBe(false);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
48
92
|
});
|
|
@@ -1,20 +1,45 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
+
import { hasRunAnyCellAtom } from "@/components/editor/cell/useRunCells";
|
|
4
|
+
import { store } from "@/core/state/jotai";
|
|
5
|
+
|
|
3
6
|
/**
|
|
4
7
|
* Whether a URL can be trusted to point at a marimo-served virtual file.
|
|
5
8
|
*
|
|
6
9
|
* Plugins that load remote scripts or stylesheets (e.g. MplInteractive, Panel)
|
|
7
10
|
* must call this before turning a plugin-supplied URL into a `<script src>` or
|
|
8
|
-
* `<link href>`. The backend
|
|
11
|
+
* `<link href>`. The backend normally serializes these URLs as virtual file
|
|
9
12
|
* paths of the form `./@file/<byte_length>-<filename>` (see
|
|
10
13
|
* `VirtualFile.create_and_register`). Accepting anything else would let a
|
|
11
14
|
* maliciously crafted `<marimo-*>` element embedded in markdown load
|
|
12
15
|
* attacker-controlled JavaScript at same origin, since the HTML sanitizer
|
|
13
16
|
* lets arbitrary marimo custom elements and attributes through.
|
|
17
|
+
*
|
|
18
|
+
* Some runtimes (WASM, VS Code) have no backend to serve virtual files, so
|
|
19
|
+
* `VirtualFile` falls back to inline base64 data URLs (see `virtual_file.py`).
|
|
20
|
+
* We accept those only once the user has explicitly run a cell in the current
|
|
21
|
+
* notebook — the same trust signal `sanitize.ts` uses to lift HTML
|
|
22
|
+
* sanitization. Running a cell requires deliberate user action and already
|
|
23
|
+
* executes arbitrary Python, so a data URL script loaded afterwards is not a
|
|
24
|
+
* new attack surface.
|
|
14
25
|
*/
|
|
15
26
|
export function isTrustedVirtualFileUrl(url: unknown): url is string {
|
|
16
27
|
if (typeof url !== "string" || url.length === 0) {
|
|
17
28
|
return false;
|
|
18
29
|
}
|
|
19
|
-
|
|
30
|
+
if (/^(\.?\/)?@file\/[^?#]+$/.test(url)) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (isSafeDataUrl(url) && store.get(hasRunAnyCellAtom)) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isSafeDataUrl(url: string): boolean {
|
|
40
|
+
return (
|
|
41
|
+
url.startsWith("data:text/javascript;base64,") ||
|
|
42
|
+
url.startsWith("data:application/javascript;base64,") ||
|
|
43
|
+
url.startsWith("data:text/css;base64,")
|
|
44
|
+
);
|
|
20
45
|
}
|