pptx-angular-viewer 1.13.0 → 1.13.1
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/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to this project are documented here.
|
|
|
4
4
|
This file is generated from [Conventional Commits](https://www.conventionalcommits.org)
|
|
5
5
|
by [git-cliff](https://git-cliff.org); do not edit it by hand.
|
|
6
6
|
|
|
7
|
+
## [1.13.0](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@1.13.0) - 2026-07-09
|
|
8
|
+
|
|
9
|
+
### Other
|
|
10
|
+
|
|
11
|
+
- Reconcile with origin/main before push (by @ChristopherVR) ([ef5fc85](https://github.com/ChristopherVR/pptx-viewer/commit/ef5fc85dca2e20ff3e105d622594e0f65d010fb0))
|
|
12
|
+
- Reconcile with origin/main before push (by @ChristopherVR) ([030b28b](https://github.com/ChristopherVR/pptx-viewer/commit/030b28bb21697ed681e4e59aa40db29f4b4a18d0))
|
|
13
|
+
|
|
7
14
|
## [1.12.0](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@1.12.0) - 2026-07-09
|
|
8
15
|
|
|
9
16
|
### Features
|
|
@@ -34036,20 +34036,47 @@ function sanitizeCssDeclaration(value) {
|
|
|
34036
34036
|
* JS callers, so a runtime check keeps the value that reaches `@page` /
|
|
34037
34037
|
* `<style>` interpolation confined to those two known-safe strings.
|
|
34038
34038
|
*/
|
|
34039
|
-
function sanitizeOrientation(value) {
|
|
34039
|
+
function sanitizeOrientation$1(value) {
|
|
34040
34040
|
return value === 'portrait' ? 'portrait' : 'landscape';
|
|
34041
34041
|
}
|
|
34042
|
+
/** Element/attribute shapes that are never legitimate in a rendered slide SVG. */
|
|
34043
|
+
const UNSAFE_SVG_SUBSTRINGS = [
|
|
34044
|
+
'</section',
|
|
34045
|
+
'<script',
|
|
34046
|
+
'<foreignobject',
|
|
34047
|
+
'<iframe',
|
|
34048
|
+
'<embed',
|
|
34049
|
+
'<object',
|
|
34050
|
+
// eslint-disable-next-line no-script-url -- security deny-list entry: verifies the scheme is rejected, never executed.
|
|
34051
|
+
'javascript:',
|
|
34052
|
+
];
|
|
34053
|
+
/** Matches an `on<event>=` handler attribute, e.g. `onload=`, `onclick=`. */
|
|
34054
|
+
const EVENT_HANDLER_ATTR_RE$1 = /\son\w+\s*=/iu;
|
|
34042
34055
|
/**
|
|
34043
34056
|
* Guard against a malformed or tampered per-slide SVG string breaking out
|
|
34044
34057
|
* of the `<section>` wrapper it's embedded in (unescaped) by
|
|
34045
|
-
* {@link buildPrintDocument}.
|
|
34046
|
-
*
|
|
34047
|
-
*
|
|
34048
|
-
*
|
|
34058
|
+
* {@link buildPrintDocument}.
|
|
34059
|
+
*
|
|
34060
|
+
* This is deliberately an allow-list first, deny-list second check, not
|
|
34061
|
+
* just a deny-list: legitimate SVG produced by this library's own
|
|
34062
|
+
* `SvgExporter` render path is always a single well-formed `<svg>...</svg>`
|
|
34063
|
+
* root element, so anything that doesn't structurally look like that is
|
|
34064
|
+
* rejected outright. The deny-list then additionally screens for common
|
|
34065
|
+
* SVG-based script-injection vectors (`<script>`, `<foreignObject>` (which
|
|
34066
|
+
* can embed arbitrary HTML), `on*=` event handler attributes, `javascript:`
|
|
34067
|
+
* URIs) so a crafted-but-still-`<svg>...</svg>`-shaped payload is also
|
|
34068
|
+
* rejected.
|
|
34049
34069
|
*/
|
|
34050
34070
|
function isSafeSvgMarkup(svg) {
|
|
34051
|
-
const
|
|
34052
|
-
|
|
34071
|
+
const trimmed = svg.trim();
|
|
34072
|
+
if (!trimmed.toLowerCase().startsWith('<svg') || !trimmed.toLowerCase().endsWith('</svg>')) {
|
|
34073
|
+
return false;
|
|
34074
|
+
}
|
|
34075
|
+
const lower = trimmed.toLowerCase();
|
|
34076
|
+
if (UNSAFE_SVG_SUBSTRINGS.some((needle) => lower.includes(needle))) {
|
|
34077
|
+
return false;
|
|
34078
|
+
}
|
|
34079
|
+
return !EVENT_HANDLER_ATTR_RE$1.test(trimmed);
|
|
34053
34080
|
}
|
|
34054
34081
|
/* ------------------------------------------------------------------ */
|
|
34055
34082
|
/* Print stylesheet / document construction */
|
|
@@ -34091,7 +34118,7 @@ function buildPrintStyleSheet(width, height, customCss) {
|
|
|
34091
34118
|
*/
|
|
34092
34119
|
function buildPrintDocument(svgs, width, height, options = {}) {
|
|
34093
34120
|
const { title = 'Print', orientation = 'landscape', colorFilter = '' } = options;
|
|
34094
|
-
const safeOrientation = sanitizeOrientation(orientation);
|
|
34121
|
+
const safeOrientation = sanitizeOrientation$1(orientation);
|
|
34095
34122
|
const safeColorFilter = sanitizeCssDeclaration(colorFilter);
|
|
34096
34123
|
const slidePages = svgs
|
|
34097
34124
|
.map((svg, i) => {
|
|
@@ -35558,12 +35585,51 @@ function buildHandoutsHtml(slideImages, slideIndices, slidesPerPage) {
|
|
|
35558
35585
|
}
|
|
35559
35586
|
return pages.join('');
|
|
35560
35587
|
}
|
|
35588
|
+
/**
|
|
35589
|
+
* `orientation` is typed as a union at compile time, but `buildPrintHtmlDocument`
|
|
35590
|
+
* is a public export reachable from plain JS callers, so a runtime check keeps
|
|
35591
|
+
* the value that reaches `@page` / `<style>` interpolation confined to those
|
|
35592
|
+
* two known-safe strings.
|
|
35593
|
+
*/
|
|
35594
|
+
function sanitizeOrientation(value) {
|
|
35595
|
+
return value === 'portrait' ? 'portrait' : 'landscape';
|
|
35596
|
+
}
|
|
35597
|
+
/** Element/attribute shapes that must never appear in assembled print-window body HTML. */
|
|
35598
|
+
const UNSAFE_BODY_HTML_SUBSTRINGS = [
|
|
35599
|
+
'<script',
|
|
35600
|
+
'<iframe',
|
|
35601
|
+
'<embed',
|
|
35602
|
+
'<object',
|
|
35603
|
+
'<foreignobject',
|
|
35604
|
+
// eslint-disable-next-line no-script-url -- security deny-list entry: verifies the scheme is rejected, never executed.
|
|
35605
|
+
'javascript:',
|
|
35606
|
+
];
|
|
35607
|
+
/** Matches an `on<event>=` handler attribute, e.g. `onload=`, `onclick=`. */
|
|
35608
|
+
const EVENT_HANDLER_ATTR_RE = /\son\w+\s*=/iu;
|
|
35609
|
+
/**
|
|
35610
|
+
* Defense-in-depth guard for the assembled print-window body HTML. Every
|
|
35611
|
+
* dynamic value the `build*Html` helpers above embed (titles, notes, image
|
|
35612
|
+
* `src`) is already escaped via {@link escapeHtml} / {@link safeDataImageSrc}
|
|
35613
|
+
* before it's spliced into `bodyHtml`; this additionally screens the
|
|
35614
|
+
* assembled fragment for script-injection shapes, so a future caller that
|
|
35615
|
+
* forgets to escape a new field doesn't reach the printed window unnoticed.
|
|
35616
|
+
*/
|
|
35617
|
+
function isSafePrintBodyHtml(html) {
|
|
35618
|
+
const lower = html.toLowerCase();
|
|
35619
|
+
if (UNSAFE_BODY_HTML_SUBSTRINGS.some((needle) => lower.includes(needle))) {
|
|
35620
|
+
return false;
|
|
35621
|
+
}
|
|
35622
|
+
return !EVENT_HANDLER_ATTR_RE.test(html);
|
|
35623
|
+
}
|
|
35561
35624
|
/**
|
|
35562
35625
|
* Assemble the complete printable HTML document string (doctype + head with
|
|
35563
35626
|
* print CSS + body). Pure: the caller writes it into a print window.
|
|
35564
35627
|
*/
|
|
35565
35628
|
function buildPrintHtmlDocument(options) {
|
|
35566
|
-
const { title, bodyHtml,
|
|
35629
|
+
const { title, bodyHtml, frameSlides } = options;
|
|
35630
|
+
const orientation = sanitizeOrientation(options.orientation);
|
|
35631
|
+
const colorFilter = options.colorFilter;
|
|
35632
|
+
const safeBodyHtml = isSafePrintBodyHtml(bodyHtml) ? bodyHtml : '';
|
|
35567
35633
|
const frameStyle = frameSlides
|
|
35568
35634
|
? 'img.slide-img, .notes-slide, .handout-cell img { border: 2px solid #000 !important; }'
|
|
35569
35635
|
: '';
|
|
@@ -35611,7 +35677,7 @@ function buildPrintHtmlDocument(options) {
|
|
|
35611
35677
|
${frameStyle}
|
|
35612
35678
|
</style>
|
|
35613
35679
|
</head>
|
|
35614
|
-
<body>${
|
|
35680
|
+
<body>${safeBodyHtml}</body>
|
|
35615
35681
|
</html>`;
|
|
35616
35682
|
}
|
|
35617
35683
|
|