Skip to content

Commit 0455d21

Browse files
authored
Merge pull request #1054 from davecardwell/main
feat: allow specifying a hook with `removeHook()`
2 parents 0ce2d47 + 1b0935e commit 0455d21

13 files changed

+143
-54
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ Feature releases will not be announced to this list.
427427
428428
Many people helped and help DOMPurify become what it is and need to be acknowledged here!
429429
430-
[hash_kitten ❤️](https://twitter.com/hash_kitten), [kevin_mizu ❤️](https://twitter.com/kevin_mizu), [icesfont ❤️](https://github.com/icesfont), [reduckted ❤️](https://github.com/reduckted), [dcramer 💸](https://github.com/dcramer), [JGraph 💸](https://github.com/jgraph), [baekilda 💸](https://github.com/baekilda), [Healthchecks 💸](https://github.com/healthchecks), [Sentry 💸](https://github.com/getsentry), [jarrodldavis 💸](https://github.com/jarrodldavis), [CynegeticIO](https://github.com/CynegeticIO), [ssi02014 ❤️](https://github.com/ssi02014), [GrantGryczan](https://github.com/GrantGryczan), [Lowdefy](https://twitter.com/lowdefy), [granlem](https://twitter.com/MaximeVeit), [oreoshake](https://github.com/oreoshake), [tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [is2ei](https://github.com/is2ei), [SoheilKhodayari](https://github.com/SoheilKhodayari), [franktopel](https://github.com/franktopel), [NateScarlet](https://github.com/NateScarlet), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [terjanq](https://twitter.com/terjanq), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro), [@CmdEngineer\_](https://twitter.com/CmdEngineer_), [@avr4mit](https://twitter.com/avr4mit) and especially [@securitymb ❤️](https://twitter.com/securitymb) & [@masatokinugawa ❤️](https://twitter.com/masatokinugawa)
430+
[hash_kitten ❤️](https://twitter.com/hash_kitten), [kevin_mizu ❤️](https://twitter.com/kevin_mizu), [icesfont ❤️](https://github.com/icesfont), [reduckted ❤️](https://github.com/reduckted), [dcramer 💸](https://github.com/dcramer), [JGraph 💸](https://github.com/jgraph), [baekilda 💸](https://github.com/baekilda), [Healthchecks 💸](https://github.com/healthchecks), [Sentry 💸](https://github.com/getsentry), [jarrodldavis 💸](https://github.com/jarrodldavis), [CynegeticIO](https://github.com/CynegeticIO), [ssi02014 ❤️](https://github.com/ssi02014), [GrantGryczan](https://github.com/GrantGryczan), [Lowdefy](https://twitter.com/lowdefy), [granlem](https://twitter.com/MaximeVeit), [oreoshake](https://github.com/oreoshake), [tdeekens ❤️](https://github.com/tdeekens), [peernohell ❤️](https://github.com/peernohell), [is2ei](https://github.com/is2ei), [SoheilKhodayari](https://github.com/SoheilKhodayari), [franktopel](https://github.com/franktopel), [NateScarlet](https://github.com/NateScarlet), [neilj](https://github.com/neilj), [fhemberger](https://github.com/fhemberger), [Joris-van-der-Wel](https://github.com/Joris-van-der-Wel), [ydaniv](https://github.com/ydaniv), [terjanq](https://twitter.com/terjanq), [filedescriptor](https://github.com/filedescriptor), [ConradIrwin](https://github.com/ConradIrwin), [gibson042](https://github.com/gibson042), [choumx](https://github.com/choumx), [0xSobky](https://github.com/0xSobky), [styfle](https://github.com/styfle), [koto](https://github.com/koto), [tlau88](https://github.com/tlau88), [strugee](https://github.com/strugee), [oparoz](https://github.com/oparoz), [mathiasbynens](https://github.com/mathiasbynens), [edg2s](https://github.com/edg2s), [dnkolegov](https://github.com/dnkolegov), [dhardtke](https://github.com/dhardtke), [wirehead](https://github.com/wirehead), [thorn0](https://github.com/thorn0), [styu](https://github.com/styu), [mozfreddyb](https://github.com/mozfreddyb), [mikesamuel](https://github.com/mikesamuel), [jorangreef](https://github.com/jorangreef), [jimmyhchan](https://github.com/jimmyhchan), [jameydeorio](https://github.com/jameydeorio), [jameskraus](https://github.com/jameskraus), [hyderali](https://github.com/hyderali), [hansottowirtz](https://github.com/hansottowirtz), [hackvertor](https://github.com/hackvertor), [freddyb](https://github.com/freddyb), [flavorjones](https://github.com/flavorjones), [djfarrelly](https://github.com/djfarrelly), [devd](https://github.com/devd), [camerondunford](https://github.com/camerondunford), [buu700](https://github.com/buu700), [buildog](https://github.com/buildog), [alabiaga](https://github.com/alabiaga), [Vector919](https://github.com/Vector919), [Robbert](https://github.com/Robbert), [GreLI](https://github.com/GreLI), [FuzzySockets](https://github.com/FuzzySockets), [ArtemBernatskyy](https://github.com/ArtemBernatskyy), [@garethheyes](https://twitter.com/garethheyes), [@shafigullin](https://twitter.com/shafigullin), [@mmrupp](https://twitter.com/mmrupp), [@irsdl](https://twitter.com/irsdl),[ShikariSenpai](https://github.com/ShikariSenpai), [ansjdnakjdnajkd](https://github.com/ansjdnakjdnajkd), [@asutherland](https://twitter.com/asutherland), [@mathias](https://twitter.com/mathias), [@cgvwzq](https://twitter.com/cgvwzq), [@robbertatwork](https://twitter.com/robbertatwork), [@giutro](https://twitter.com/giutro), [@CmdEngineer\_](https://twitter.com/CmdEngineer_), [@avr4mit](https://twitter.com/avr4mit), [davecardwell](https://github.com/davecardwell) and especially [@securitymb ❤️](https://twitter.com/securitymb) & [@masatokinugawa ❤️](https://twitter.com/masatokinugawa)
431431
432432
## Testing powered by
433433

dist/purify.cjs.d.ts

+20-15
Original file line numberDiff line numberDiff line change
@@ -329,44 +329,49 @@ interface DOMPurify {
329329
addHook(entryPoint: 'uponSanitizeAttribute', hookFunction: UponSanitizeAttributeHook): void;
330330
/**
331331
* Remove a DOMPurify hook at a given entryPoint
332-
* (pops it from the stack of hooks if more are present)
332+
* (pops it from the stack of hooks if hook not specified)
333333
*
334334
* @param entryPoint entry point for the hook to remove
335-
* @returns removed(popped) hook
335+
* @param hookFunction optional specific hook to remove
336+
* @returns removed hook
336337
*/
337-
removeHook(entryPoint: BasicHookName): NodeHook | undefined;
338+
removeHook(entryPoint: BasicHookName, hookFunction?: NodeHook): NodeHook | undefined;
338339
/**
339340
* Remove a DOMPurify hook at a given entryPoint
340-
* (pops it from the stack of hooks if more are present)
341+
* (pops it from the stack of hooks if hook not specified)
341342
*
342343
* @param entryPoint entry point for the hook to remove
343-
* @returns removed(popped) hook
344+
* @param hookFunction optional specific hook to remove
345+
* @returns removed hook
344346
*/
345-
removeHook(entryPoint: ElementHookName): ElementHook | undefined;
347+
removeHook(entryPoint: ElementHookName, hookFunction?: ElementHook): ElementHook | undefined;
346348
/**
347349
* Remove a DOMPurify hook at a given entryPoint
348-
* (pops it from the stack of hooks if more are present)
350+
* (pops it from the stack of hooks if hook not specified)
349351
*
350352
* @param entryPoint entry point for the hook to remove
351-
* @returns removed(popped) hook
353+
* @param hookFunction optional specific hook to remove
354+
* @returns removed hook
352355
*/
353-
removeHook(entryPoint: DocumentFragmentHookName): DocumentFragmentHook | undefined;
356+
removeHook(entryPoint: DocumentFragmentHookName, hookFunction?: DocumentFragmentHook): DocumentFragmentHook | undefined;
354357
/**
355358
* Remove a DOMPurify hook at a given entryPoint
356-
* (pops it from the stack of hooks if more are present)
359+
* (pops it from the stack of hooks if hook not specified)
357360
*
358361
* @param entryPoint entry point for the hook to remove
359-
* @returns removed(popped) hook
362+
* @param hookFunction optional specific hook to remove
363+
* @returns removed hook
360364
*/
361-
removeHook(entryPoint: 'uponSanitizeElement'): UponSanitizeElementHook | undefined;
365+
removeHook(entryPoint: 'uponSanitizeElement', hookFunction?: UponSanitizeElementHook): UponSanitizeElementHook | undefined;
362366
/**
363367
* Remove a DOMPurify hook at a given entryPoint
364-
* (pops it from the stack of hooks if more are present)
368+
* (pops it from the stack of hooks if hook not specified)
365369
*
366370
* @param entryPoint entry point for the hook to remove
367-
* @returns removed(popped) hook
371+
* @param hookFunction optional specific hook to remove
372+
* @returns removed hook
368373
*/
369-
removeHook(entryPoint: 'uponSanitizeAttribute'): UponSanitizeAttributeHook | undefined;
374+
removeHook(entryPoint: 'uponSanitizeAttribute', hookFunction?: UponSanitizeAttributeHook): UponSanitizeAttributeHook | undefined;
370375
/**
371376
* Removes all DOMPurify hooks at a given entryPoint
372377
*

dist/purify.cjs.js

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.cjs.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/purify.es.d.mts

+20-15
Original file line numberDiff line numberDiff line change
@@ -329,44 +329,49 @@ interface DOMPurify {
329329
addHook(entryPoint: 'uponSanitizeAttribute', hookFunction: UponSanitizeAttributeHook): void;
330330
/**
331331
* Remove a DOMPurify hook at a given entryPoint
332-
* (pops it from the stack of hooks if more are present)
332+
* (pops it from the stack of hooks if hook not specified)
333333
*
334334
* @param entryPoint entry point for the hook to remove
335-
* @returns removed(popped) hook
335+
* @param hookFunction optional specific hook to remove
336+
* @returns removed hook
336337
*/
337-
removeHook(entryPoint: BasicHookName): NodeHook | undefined;
338+
removeHook(entryPoint: BasicHookName, hookFunction?: NodeHook): NodeHook | undefined;
338339
/**
339340
* Remove a DOMPurify hook at a given entryPoint
340-
* (pops it from the stack of hooks if more are present)
341+
* (pops it from the stack of hooks if hook not specified)
341342
*
342343
* @param entryPoint entry point for the hook to remove
343-
* @returns removed(popped) hook
344+
* @param hookFunction optional specific hook to remove
345+
* @returns removed hook
344346
*/
345-
removeHook(entryPoint: ElementHookName): ElementHook | undefined;
347+
removeHook(entryPoint: ElementHookName, hookFunction?: ElementHook): ElementHook | undefined;
346348
/**
347349
* Remove a DOMPurify hook at a given entryPoint
348-
* (pops it from the stack of hooks if more are present)
350+
* (pops it from the stack of hooks if hook not specified)
349351
*
350352
* @param entryPoint entry point for the hook to remove
351-
* @returns removed(popped) hook
353+
* @param hookFunction optional specific hook to remove
354+
* @returns removed hook
352355
*/
353-
removeHook(entryPoint: DocumentFragmentHookName): DocumentFragmentHook | undefined;
356+
removeHook(entryPoint: DocumentFragmentHookName, hookFunction?: DocumentFragmentHook): DocumentFragmentHook | undefined;
354357
/**
355358
* Remove a DOMPurify hook at a given entryPoint
356-
* (pops it from the stack of hooks if more are present)
359+
* (pops it from the stack of hooks if hook not specified)
357360
*
358361
* @param entryPoint entry point for the hook to remove
359-
* @returns removed(popped) hook
362+
* @param hookFunction optional specific hook to remove
363+
* @returns removed hook
360364
*/
361-
removeHook(entryPoint: 'uponSanitizeElement'): UponSanitizeElementHook | undefined;
365+
removeHook(entryPoint: 'uponSanitizeElement', hookFunction?: UponSanitizeElementHook): UponSanitizeElementHook | undefined;
362366
/**
363367
* Remove a DOMPurify hook at a given entryPoint
364-
* (pops it from the stack of hooks if more are present)
368+
* (pops it from the stack of hooks if hook not specified)
365369
*
366370
* @param entryPoint entry point for the hook to remove
367-
* @returns removed(popped) hook
371+
* @param hookFunction optional specific hook to remove
372+
* @returns removed hook
368373
*/
369-
removeHook(entryPoint: 'uponSanitizeAttribute'): UponSanitizeAttributeHook | undefined;
374+
removeHook(entryPoint: 'uponSanitizeAttribute', hookFunction?: UponSanitizeAttributeHook): UponSanitizeAttributeHook | undefined;
370375
/**
371376
* Removes all DOMPurify hooks at a given entryPoint
372377
*

dist/purify.es.mjs

+7-1
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@ if (!construct) {
3737
};
3838
}
3939
const arrayForEach = unapply(Array.prototype.forEach);
40+
const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
4041
const arrayPop = unapply(Array.prototype.pop);
4142
const arrayPush = unapply(Array.prototype.push);
43+
const arraySplice = unapply(Array.prototype.splice);
4244
const stringToLowerCase = unapply(String.prototype.toLowerCase);
4345
const stringToString = unapply(String.prototype.toString);
4446
const stringMatch = unapply(String.prototype.match);
@@ -1315,7 +1317,11 @@ function createDOMPurify() {
13151317
}
13161318
arrayPush(hooks[entryPoint], hookFunction);
13171319
};
1318-
DOMPurify.removeHook = function (entryPoint) {
1320+
DOMPurify.removeHook = function (entryPoint, hookFunction) {
1321+
if (hookFunction !== undefined) {
1322+
const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
1323+
return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];
1324+
}
13191325
return arrayPop(hooks[entryPoint]);
13201326
};
13211327
DOMPurify.removeHooks = function (entryPoint) {

0 commit comments

Comments
 (0)