houdini_html_e.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "houdini.h"
  5. /**
  6. * According to the OWASP rules:
  7. *
  8. * & --> &amp;
  9. * < --> &lt;
  10. * > --> &gt;
  11. * " --> &quot;
  12. * ' --> &#x27; &apos; is not recommended
  13. * / --> &#x2F; forward slash is included as it helps end an HTML entity
  14. *
  15. */
  16. static const char HTML_ESCAPE_TABLE[] = {
  17. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  18. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4,
  19. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  20. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  21. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  22. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  23. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  24. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  25. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  26. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  27. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  28. };
  29. static const char *HTML_ESCAPES[] = {"", "&quot;", "&amp;", "&#39;",
  30. "&#47;", "&lt;", "&gt;"};
  31. int houdini_escape_html0(cmark_strbuf *ob, const uint8_t *src, bufsize_t size,
  32. int secure) {
  33. bufsize_t i = 0, org, esc = 0;
  34. while (i < size) {
  35. org = i;
  36. while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)
  37. i++;
  38. if (i > org)
  39. cmark_strbuf_put(ob, src + org, i - org);
  40. /* escaping */
  41. if (unlikely(i >= size))
  42. break;
  43. /* The forward slash is only escaped in secure mode */
  44. if ((src[i] == '/' || src[i] == '\'') && !secure) {
  45. cmark_strbuf_putc(ob, src[i]);
  46. } else {
  47. cmark_strbuf_puts(ob, HTML_ESCAPES[esc]);
  48. }
  49. i++;
  50. }
  51. return 1;
  52. }
  53. int houdini_escape_html(cmark_strbuf *ob, const uint8_t *src, bufsize_t size) {
  54. return houdini_escape_html0(ob, src, size, 1);
  55. }