|
Lines 158-164
subtest 'note scrubber functionality' => sub {
Link Here
|
| 158 |
}; |
158 |
}; |
| 159 |
|
159 |
|
| 160 |
subtest 'record_display profile tests' => sub { |
160 |
subtest 'record_display profile tests' => sub { |
| 161 |
plan tests => 26; |
161 |
plan tests => 27; |
| 162 |
|
162 |
|
| 163 |
my $scrubber = C4::Scrubber->new('record_display'); |
163 |
my $scrubber = C4::Scrubber->new('record_display'); |
| 164 |
|
164 |
|
|
Lines 318-321
subtest 'record_display profile tests' => sub {
Link Here
|
| 318 |
'<ul><li>Bad class</li></ul>', |
318 |
'<ul><li>Bad class</li></ul>', |
| 319 |
'invalid list class attribute removed' |
319 |
'invalid list class attribute removed' |
| 320 |
); |
320 |
); |
|
|
321 |
|
| 322 |
subtest 'opac profile tests' => sub { |
| 323 |
plan tests => 20; |
| 324 |
|
| 325 |
my $scrubber = C4::Scrubber->new('opac'); |
| 326 |
|
| 327 |
# Test basic allowed elements |
| 328 |
is( |
| 329 |
$scrubber->scrub('<div id="card-container" class="virtual-card">hello world!</div>'), |
| 330 |
'<div id="card-container" class="virtual-card">hello world!</div>', |
| 331 |
'div with id and class allowed' |
| 332 |
); |
| 333 |
|
| 334 |
is( |
| 335 |
$scrubber->scrub('<p id="patron-name" class="card-text">Luke G</p>'), |
| 336 |
'<p id="patron-name" class="card-text">Luke G</p>', |
| 337 |
'p with id and class allowed' |
| 338 |
); |
| 339 |
|
| 340 |
is( |
| 341 |
$scrubber->scrub('<span class="highlight">Important</span>'), |
| 342 |
'<span class="highlight">Important</span>', |
| 343 |
'span with class allowed' |
| 344 |
); |
| 345 |
|
| 346 |
is( |
| 347 |
$scrubber->scrub('<h1>Card Title</h1><h2>supercalifragilisticexpialidocious</h2>'), |
| 348 |
'<h1>Card Title</h1><h2>supercalifragilisticexpialidocious</h2>', |
| 349 |
'heading elements allowed' |
| 350 |
); |
| 351 |
|
| 352 |
# Test SVG with barcode attributes |
| 353 |
is( |
| 354 |
$scrubber->scrub('<svg id="patron-barcode" data-barcode="42" data-barcode-format="code39"></svg>'), |
| 355 |
'<svg id="patron-barcode" data-barcode="42" data-barcode-format="code39"></svg>', |
| 356 |
'svg with barcode attributes allowed' |
| 357 |
); |
| 358 |
|
| 359 |
is( |
| 360 |
$scrubber->scrub( |
| 361 |
'<div id="barcode-container"><svg id="patron-barcode" data-barcode="123456" data-barcode-format="qrcode"></svg></div>' |
| 362 |
), |
| 363 |
'<div id="barcode-container"><svg id="patron-barcode" data-barcode="123456" data-barcode-format="qrcode"></svg></div>', |
| 364 |
'div with svg barcode inside preserved' |
| 365 |
); |
| 366 |
|
| 367 |
# Test list elements |
| 368 |
is( |
| 369 |
$scrubber->scrub('<ul><li>Item 1</li><li>Item 2</li></ul>'), |
| 370 |
'<ul><li>Item 1</li><li>Item 2</li></ul>', |
| 371 |
'unordered lists allowed' |
| 372 |
); |
| 373 |
|
| 374 |
is( |
| 375 |
$scrubber->scrub('<ol><li>First</li><li>Second</li></ol>'), |
| 376 |
'<ol><li>First</li><li>Second</li></ol>', |
| 377 |
'ordered lists allowed' |
| 378 |
); |
| 379 |
|
| 380 |
is( |
| 381 |
$scrubber->scrub('<dl><dt>Term</dt><dd>Definition</dd></dl>'), |
| 382 |
'<dl><dt>Term</dt><dd>Definition</dd></dl>', |
| 383 |
'definition lists allowed' |
| 384 |
); |
| 385 |
|
| 386 |
# Test text formatting |
| 387 |
is( |
| 388 |
$scrubber->scrub('<strong>Bold</strong> <em>Italic</em> <u>Underline</u>'), |
| 389 |
'<strong>Bold</strong> <em>Italic</em> <u>Underline</u>', |
| 390 |
'text formatting elements allowed' |
| 391 |
); |
| 392 |
|
| 393 |
is( |
| 394 |
$scrubber->scrub('<b>Bold</b> <i>Italic</i>'), |
| 395 |
'<b>Bold</b> <i>Italic</i>', |
| 396 |
'alternative text formatting allowed' |
| 397 |
); |
| 398 |
|
| 399 |
is( |
| 400 |
$scrubber->scrub('<p>Line 1<br>Line 2</p>'), |
| 401 |
'<p>Line 1<br>Line 2</p>', |
| 402 |
'br tags allowed' |
| 403 |
); |
| 404 |
|
| 405 |
is( |
| 406 |
$scrubber->scrub('<hr>'), |
| 407 |
'<hr>', |
| 408 |
'hr tags allowed' |
| 409 |
); |
| 410 |
|
| 411 |
# Test security - malicious content removal |
| 412 |
is( |
| 413 |
$scrubber->scrub('<script>alert("xss")</script><div>Safe content</div>'), |
| 414 |
'<div>Safe content</div>', |
| 415 |
'script tags removed while safe content preserved' |
| 416 |
); |
| 417 |
|
| 418 |
is( |
| 419 |
$scrubber->scrub('<div onclick="evil()">Content</div>'), |
| 420 |
'<div>Content</div>', |
| 421 |
'onclick handler removed' |
| 422 |
); |
| 423 |
|
| 424 |
is( |
| 425 |
$scrubber->scrub( |
| 426 |
'<svg id="barcode" onload="alert(1)" data-barcode="42" data-barcode-format="code39"></svg>'), |
| 427 |
'<svg id="barcode" data-barcode="42" data-barcode-format="code39"></svg>', |
| 428 |
'svg onload handler removed while valid attributes preserved' |
| 429 |
); |
| 430 |
|
| 431 |
is( |
| 432 |
$scrubber->scrub('<div style="background:url(javascript:alert(1))">Content</div>'), |
| 433 |
'<div>Content</div>', |
| 434 |
'inline styles removed' |
| 435 |
); |
| 436 |
|
| 437 |
# Test invalid attribute removal |
| 438 |
is( |
| 439 |
$scrubber->scrub('<div id="invalid id with spaces">Test</div>'), |
| 440 |
'<div>Test</div>', |
| 441 |
'invalid id with spaces removed' |
| 442 |
); |
| 443 |
|
| 444 |
is( |
| 445 |
$scrubber->scrub('<svg data-barcode="42" data-invalid="bad">Content</svg>'), |
| 446 |
'<svg data-barcode="42">Content</svg>', |
| 447 |
'invalid svg attributes removed' |
| 448 |
); |
| 449 |
|
| 450 |
# Test comprehensive virtual card example |
| 451 |
my $card_html = |
| 452 |
'<div id="barcode-container"><svg id="patron-barcode" data-barcode="42" data-barcode-format="code39"></svg></div><br><div id="lib-container"><p id="patron-lib"><strong>Library:</strong> Centerville</p></div><div id="cardnumber-container"><p id="patron-cardnumber"><strong>Card number:</strong> 42</p></div>'; |
| 453 |
is( |
| 454 |
$scrubber->scrub($card_html), |
| 455 |
$card_html, |
| 456 |
'complete virtual card HTML preserved' |
| 457 |
); |
| 458 |
}; |
| 321 |
}; |
459 |
}; |
| 322 |
- |
|
|