lexxy-variables 0.0.4 → 0.0.5

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.
Files changed (346) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +85 -60
  3. data/lib/lexxy_variables/configuration.rb +1 -3
  4. data/lib/lexxy_variables/helper.rb +4 -17
  5. data/lib/lexxy_variables/renderers/liquid.rb +8 -12
  6. data/lib/lexxy_variables/renderers/substitution.rb +6 -8
  7. data/lib/lexxy_variables/{pipeline.rb → resolver.rb} +29 -23
  8. data/lib/lexxy_variables/version.rb +1 -1
  9. data/lib/lexxy_variables/with_variables.rb +31 -0
  10. data/lib/lexxy_variables.rb +4 -4
  11. data/vendor/bundle/ruby/3.4.0/cache/concurrent-ruby-1.3.8.gem +0 -0
  12. data/vendor/bundle/ruby/3.4.0/cache/erb-6.0.5.gem +0 -0
  13. data/vendor/bundle/ruby/3.4.0/cache/lexxy-0.9.25.gem +0 -0
  14. data/vendor/bundle/ruby/3.4.0/cache/loofah-2.25.2.gem +0 -0
  15. data/vendor/bundle/ruby/3.4.0/cache/parser-3.3.12.0.gem +0 -0
  16. data/vendor/bundle/ruby/3.4.0/cache/rails-html-sanitizer-1.7.1.gem +0 -0
  17. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{erb-6.0.4 → erb-6.0.5}/erb/escape.so +0 -0
  18. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-6.0.5/gem_make.out +19 -0
  19. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{lexxy-0.9.24 → lexxy-0.9.25}/gem_make.out +2 -2
  20. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/CHANGELOG.md +6 -0
  21. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concurrent_ruby.jar +0 -0
  22. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/constants.rb +1 -1
  23. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/promises.rb +8 -2
  24. data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/version.rb +1 -1
  25. data/vendor/bundle/ruby/3.4.0/gems/erb-6.0.5/Gemfile +16 -0
  26. data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/NEWS.md +17 -1
  27. data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/escape.so +0 -0
  28. data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/version.rb +1 -1
  29. data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb.rb +11 -3
  30. data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/javascript/lexxy.js +66 -9
  31. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.js.br +0 -0
  32. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.js.gz +0 -0
  33. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.js.map +1 -0
  34. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.min.js +11 -0
  35. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.min.js.br +0 -0
  36. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/app/assets/javascript/lexxy.min.js.gz +0 -0
  37. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.25/lib/lexxy/version.rb +3 -0
  38. data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/CHANGELOG.md +15 -0
  39. data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/safelist.rb +6 -2
  40. data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/scrub.rb +86 -13
  41. data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/version.rb +1 -1
  42. data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/current.rb +1 -1
  43. data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/version.rb +1 -1
  44. data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/CHANGELOG.md +15 -0
  45. data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/lib/rails/html/sanitizer/version.rb +1 -1
  46. data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/lib/rails/html/scrubbers.rb +1 -1
  47. data/vendor/bundle/ruby/3.4.0/specifications/{concurrent-ruby-1.3.7.gemspec → concurrent-ruby-1.3.8.gemspec} +3 -3
  48. data/vendor/bundle/ruby/3.4.0/specifications/{erb-6.0.4.gemspec → erb-6.0.5.gemspec} +3 -3
  49. data/vendor/bundle/ruby/3.4.0/specifications/{lexxy-0.9.24.gemspec → lexxy-0.9.25.gemspec} +2 -2
  50. data/vendor/bundle/ruby/3.4.0/specifications/{loofah-2.25.1.gemspec → loofah-2.25.2.gemspec} +3 -3
  51. data/vendor/bundle/ruby/3.4.0/specifications/{parser-3.3.11.1.gemspec → parser-3.3.12.0.gemspec} +4 -4
  52. data/vendor/bundle/ruby/3.4.0/specifications/{rails-html-sanitizer-1.7.0.gemspec → rails-html-sanitizer-1.7.1.gemspec} +5 -5
  53. metadata +325 -327
  54. data/vendor/bundle/ruby/3.4.0/cache/concurrent-ruby-1.3.7.gem +0 -0
  55. data/vendor/bundle/ruby/3.4.0/cache/erb-6.0.4.gem +0 -0
  56. data/vendor/bundle/ruby/3.4.0/cache/lexxy-0.9.24.gem +0 -0
  57. data/vendor/bundle/ruby/3.4.0/cache/loofah-2.25.1.gem +0 -0
  58. data/vendor/bundle/ruby/3.4.0/cache/parser-3.3.11.1.gem +0 -0
  59. data/vendor/bundle/ruby/3.4.0/cache/rails-html-sanitizer-1.7.0.gem +0 -0
  60. data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-6.0.4/gem_make.out +0 -19
  61. data/vendor/bundle/ruby/3.4.0/gems/erb-6.0.4/Gemfile +0 -11
  62. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.js.br +0 -0
  63. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.js.gz +0 -0
  64. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.js.map +0 -1
  65. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.min.js +0 -11
  66. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.min.js.br +0 -0
  67. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/app/assets/javascript/lexxy.min.js.gz +0 -0
  68. data/vendor/bundle/ruby/3.4.0/gems/lexxy-0.9.24/lib/lexxy/version.rb +0 -3
  69. data/vendor/bundle/ruby/3.4.0/gems/rails-html-sanitizer-1.7.0/test/rails_api_test.rb +0 -101
  70. data/vendor/bundle/ruby/3.4.0/gems/rails-html-sanitizer-1.7.0/test/sanitizer_test.rb +0 -1284
  71. data/vendor/bundle/ruby/3.4.0/gems/rails-html-sanitizer-1.7.0/test/scrubbers_test.rb +0 -294
  72. data/vendor/bundle/ruby/3.4.0/gems/rails-html-sanitizer-1.7.0/test/test_helper.rb +0 -7
  73. /data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{erb-6.0.4 → erb-6.0.5}/gem.build_complete +0 -0
  74. /data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{erb-6.0.4 → erb-6.0.5}/mkmf.log +0 -0
  75. /data/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/{lexxy-0.9.24 → lexxy-0.9.25}/gem.build_complete +0 -0
  76. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/Gemfile +0 -0
  77. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/LICENSE.txt +0 -0
  78. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/README.md +0 -0
  79. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/Rakefile +0 -0
  80. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/ConcurrentRubyService.java +0 -0
  81. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java +0 -0
  82. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java +0 -0
  83. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java +0 -0
  84. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java +0 -0
  85. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java +0 -0
  86. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java +0 -0
  87. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java +0 -0
  88. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java +0 -0
  89. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java +0 -0
  90. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java +0 -0
  91. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java +0 -0
  92. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java +0 -0
  93. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java +0 -0
  94. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java +0 -0
  95. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/agent.rb +0 -0
  96. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/array.rb +0 -0
  97. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/async.rb +0 -0
  98. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atom.rb +0 -0
  99. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb +0 -0
  100. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb +0 -0
  101. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb +0 -0
  102. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb +0 -0
  103. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb +0 -0
  104. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb +0 -0
  105. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/event.rb +0 -0
  106. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb +0 -0
  107. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb +0 -0
  108. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/locals.rb +0 -0
  109. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb +0 -0
  110. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb +0 -0
  111. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb +0 -0
  112. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb +0 -0
  113. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb +0 -0
  114. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb +0 -0
  115. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +0 -0
  116. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/semaphore.rb +0 -0
  117. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb +0 -0
  118. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb +0 -0
  119. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb +0 -0
  120. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb +0 -0
  121. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/atomics.rb +0 -0
  122. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb +0 -0
  123. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb +0 -0
  124. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb +0 -0
  125. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb +0 -0
  126. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb +0 -0
  127. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb +0 -0
  128. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb +0 -0
  129. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb +0 -0
  130. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb +0 -0
  131. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb +0 -0
  132. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/ruby_timeout_queue.rb +0 -0
  133. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/collection/timeout_queue.rb +0 -0
  134. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/deprecation.rb +0 -0
  135. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb +0 -0
  136. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/logging.rb +0 -0
  137. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/obligation.rb +0 -0
  138. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/concern/observable.rb +0 -0
  139. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/configuration.rb +0 -0
  140. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/dataflow.rb +0 -0
  141. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/delay.rb +0 -0
  142. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/errors.rb +0 -0
  143. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/exchanger.rb +0 -0
  144. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb +0 -0
  145. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb +0 -0
  146. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/executor_service.rb +0 -0
  147. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb +0 -0
  148. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb +0 -0
  149. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb +0 -0
  150. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb +0 -0
  151. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb +0 -0
  152. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb +0 -0
  153. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb +0 -0
  154. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb +0 -0
  155. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb +0 -0
  156. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb +0 -0
  157. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb +0 -0
  158. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb +0 -0
  159. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb +0 -0
  160. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb +0 -0
  161. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb +0 -0
  162. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb +0 -0
  163. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executor/timer_set.rb +0 -0
  164. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/executors.rb +0 -0
  165. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/future.rb +0 -0
  166. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/hash.rb +0 -0
  167. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/immutable_struct.rb +0 -0
  168. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/ivar.rb +0 -0
  169. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/map.rb +0 -0
  170. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/maybe.rb +0 -0
  171. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/mutable_struct.rb +0 -0
  172. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/mvar.rb +0 -0
  173. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/options.rb +0 -0
  174. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/promise.rb +0 -0
  175. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/re_include.rb +0 -0
  176. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/scheduled_task.rb +0 -0
  177. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/set.rb +0 -0
  178. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/settable_struct.rb +0 -0
  179. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb +0 -0
  180. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb +0 -0
  181. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb +0 -0
  182. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/condition.rb +0 -0
  183. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb +0 -0
  184. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb +0 -0
  185. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/lock.rb +0 -0
  186. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb +0 -0
  187. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb +0 -0
  188. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/object.rb +0 -0
  189. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb +0 -0
  190. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization/volatile.rb +0 -0
  191. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/synchronization.rb +0 -0
  192. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb +0 -0
  193. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb +0 -0
  194. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb +0 -0
  195. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb +0 -0
  196. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb +0 -0
  197. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb +0 -0
  198. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb +0 -0
  199. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/thread_safe/util.rb +0 -0
  200. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/timer_task.rb +0 -0
  201. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/tuple.rb +0 -0
  202. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/tvar.rb +0 -0
  203. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/engine.rb +0 -0
  204. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb +0 -0
  205. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb +0 -0
  206. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/native_integer.rb +0 -0
  207. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent/utility/processor_counter.rb +0 -0
  208. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent-ruby.rb +0 -0
  209. /data/vendor/bundle/ruby/3.4.0/gems/{concurrent-ruby-1.3.7 → concurrent-ruby-1.3.8}/lib/concurrent-ruby/concurrent.rb +0 -0
  210. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/BSDL +0 -0
  211. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/COPYING +0 -0
  212. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/LICENSE.txt +0 -0
  213. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/README.md +0 -0
  214. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/Rakefile +0 -0
  215. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/_doc/cgi.rb +0 -0
  216. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/_doc/erb_executable.md +0 -0
  217. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/bin/console +0 -0
  218. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/bin/setup +0 -0
  219. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/erb.gemspec +0 -0
  220. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/ext/erb/escape/Makefile +0 -0
  221. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/ext/erb/escape/escape.c +0 -0
  222. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/ext/erb/escape/extconf.rb +0 -0
  223. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/compiler.rb +0 -0
  224. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/def_method.rb +0 -0
  225. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/lib/erb/util.rb +0 -0
  226. /data/vendor/bundle/ruby/3.4.0/gems/{erb-6.0.4 → erb-6.0.5}/libexec/erb +0 -0
  227. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/MIT-LICENSE +0 -0
  228. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/README.md +0 -0
  229. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/Rakefile +0 -0
  230. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/stylesheets/lexxy-content.css +0 -0
  231. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/stylesheets/lexxy-editor.css +0 -0
  232. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/stylesheets/lexxy-variables.css +0 -0
  233. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/assets/stylesheets/lexxy.css +0 -0
  234. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/app/views/action_text/attachables/_remote_video.html.erb +0 -0
  235. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/config/ci.rb +0 -0
  236. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/ext/Rakefile +0 -0
  237. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/action_text/attachables/remote_video.rb +0 -0
  238. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/action_text/editor/lexxy_editor.rb +0 -0
  239. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/active_storage/blob_with_preview_url.rb +0 -0
  240. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/action_text_tag.rb +0 -0
  241. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/attachable.rb +0 -0
  242. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/engine.rb +0 -0
  243. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/form_builder.rb +0 -0
  244. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/form_helper.rb +0 -0
  245. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy/rich_text_area_tag.rb +0 -0
  246. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/lexxy.rb +0 -0
  247. /data/vendor/bundle/ruby/3.4.0/gems/{lexxy-0.9.24 → lexxy-0.9.25}/lib/tasks/actiontext/lexical_tasks.rake +0 -0
  248. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/MIT-LICENSE.txt +0 -0
  249. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/README.md +0 -0
  250. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/SECURITY.md +0 -0
  251. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/concerns.rb +0 -0
  252. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/elements.rb +0 -0
  253. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/helpers.rb +0 -0
  254. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html4/document.rb +0 -0
  255. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html4/document_fragment.rb +0 -0
  256. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/document.rb +0 -0
  257. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/document_fragment.rb +0 -0
  258. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/html5/libxml2_workarounds.rb +0 -0
  259. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/metahelpers.rb +0 -0
  260. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/scrubber.rb +0 -0
  261. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/scrubbers.rb +0 -0
  262. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/xml/document.rb +0 -0
  263. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah/xml/document_fragment.rb +0 -0
  264. /data/vendor/bundle/ruby/3.4.0/gems/{loofah-2.25.1 → loofah-2.25.2}/lib/loofah.rb +0 -0
  265. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/LICENSE.txt +0 -0
  266. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/bin/ruby-parse +0 -0
  267. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/bin/ruby-rewrite +0 -0
  268. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/gauntlet_parser.rb +0 -0
  269. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/all.rb +0 -0
  270. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ast/node.rb +0 -0
  271. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ast/processor.rb +0 -0
  272. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/base.rb +0 -0
  273. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/builders/default.rb +0 -0
  274. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/clobbering_error.rb +0 -0
  275. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/color.rb +0 -0
  276. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/context.rb +0 -0
  277. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/current_arg_stack.rb +0 -0
  278. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/deprecation.rb +0 -0
  279. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/diagnostic/engine.rb +0 -0
  280. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/diagnostic.rb +0 -0
  281. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer/dedenter.rb +0 -0
  282. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer/explanation.rb +0 -0
  283. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer/literal.rb +0 -0
  284. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer/stack_state.rb +0 -0
  285. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer-F0.rb +0 -0
  286. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer-F1.rb +0 -0
  287. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/lexer-strings.rb +0 -0
  288. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/macruby.rb +0 -0
  289. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/max_numparam_stack.rb +0 -0
  290. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/messages.rb +0 -0
  291. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/meta.rb +0 -0
  292. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/rewriter.rb +0 -0
  293. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby18.rb +0 -0
  294. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby19.rb +0 -0
  295. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby20.rb +0 -0
  296. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby21.rb +0 -0
  297. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby22.rb +0 -0
  298. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby23.rb +0 -0
  299. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby24.rb +0 -0
  300. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby25.rb +0 -0
  301. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby26.rb +0 -0
  302. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby27.rb +0 -0
  303. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby30.rb +0 -0
  304. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby31.rb +0 -0
  305. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby32.rb +0 -0
  306. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby33.rb +0 -0
  307. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/ruby34.rb +0 -0
  308. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/rubymotion.rb +0 -0
  309. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/runner/ruby_parse.rb +0 -0
  310. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/runner/ruby_rewrite.rb +0 -0
  311. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/runner.rb +0 -0
  312. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/buffer.rb +0 -0
  313. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/comment/associator.rb +0 -0
  314. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/comment.rb +0 -0
  315. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/collection.rb +0 -0
  316. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/condition.rb +0 -0
  317. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/constant.rb +0 -0
  318. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/definition.rb +0 -0
  319. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/for.rb +0 -0
  320. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/heredoc.rb +0 -0
  321. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/index.rb +0 -0
  322. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/keyword.rb +0 -0
  323. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/method_definition.rb +0 -0
  324. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/objc_kwarg.rb +0 -0
  325. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/operator.rb +0 -0
  326. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/rescue_body.rb +0 -0
  327. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/send.rb +0 -0
  328. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/ternary.rb +0 -0
  329. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map/variable.rb +0 -0
  330. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/map.rb +0 -0
  331. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/range.rb +0 -0
  332. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/rewriter/action.rb +0 -0
  333. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/rewriter.rb +0 -0
  334. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/tree_rewriter/action.rb +0 -0
  335. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/source/tree_rewriter.rb +0 -0
  336. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/static_environment.rb +0 -0
  337. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/syntax_error.rb +0 -0
  338. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/tree_rewriter.rb +0 -0
  339. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/unknown_encoding_in_magic_comment_error.rb +0 -0
  340. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser/variables_stack.rb +0 -0
  341. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/lib/parser.rb +0 -0
  342. /data/vendor/bundle/ruby/3.4.0/gems/{parser-3.3.11.1 → parser-3.3.12.0}/parser.gemspec +0 -0
  343. /data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/MIT-LICENSE +0 -0
  344. /data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/README.md +0 -0
  345. /data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/lib/rails/html/sanitizer.rb +0 -0
  346. /data/vendor/bundle/ruby/3.4.0/gems/{rails-html-sanitizer-1.7.0 → rails-html-sanitizer-1.7.1}/lib/rails-html-sanitizer.rb +0 -0
@@ -1,1284 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "test_helper"
4
-
5
- #
6
- # NOTE that many of these tests contain multiple acceptable results.
7
- #
8
- # In some cases, this is because of how the HTML4 parser's recovery behavior changed in libxml2
9
- # 2.9.14 and 2.10.0. For more details, see:
10
- #
11
- # - https://github.com/sparklemotion/nokogiri/releases/tag/v1.13.5
12
- # - https://gitlab.gnome.org/GNOME/libxml2/-/issues/380
13
- #
14
- # In other cases, multiple acceptable results are provided because Nokogiri's vendored libxml2 is
15
- # patched to entity-escape server-side includes (aks "SSI", aka `<!-- #directive param=value -->`).
16
- #
17
- # In many other cases, it's because the parser used by Nokogiri on JRuby (xerces+nekohtml) parses
18
- # slightly differently than libxml2 in edge cases.
19
- #
20
- module SanitizerTests
21
- def self.loofah_html5_support?
22
- Loofah.respond_to?(:html5_support?) && Loofah.html5_support?
23
- end
24
-
25
- class BaseSanitizerTest < Minitest::Test
26
- class XpathRemovalTestSanitizer < Rails::HTML::Sanitizer
27
- def sanitize(html, options = {})
28
- fragment = Loofah.fragment(html)
29
- remove_xpaths(fragment, options[:xpaths]).to_s
30
- end
31
- end
32
-
33
- def test_sanitizer_sanitize_raises_not_implemented_error
34
- assert_raises NotImplementedError do
35
- Rails::HTML::Sanitizer.new.sanitize("asdf")
36
- end
37
- end
38
-
39
- def test_remove_xpaths_removes_an_xpath
40
- html = %(<h1>hello <script>code!</script></h1>)
41
- assert_equal %(<h1>hello </h1>), xpath_sanitize(html, xpaths: %w(.//script))
42
- end
43
-
44
- def test_remove_xpaths_removes_all_occurrences_of_xpath
45
- html = %(<section><header><script>code!</script></header><p>hello <script>code!</script></p></section>)
46
- assert_equal %(<section><header></header><p>hello </p></section>), xpath_sanitize(html, xpaths: %w(.//script))
47
- end
48
-
49
- def test_remove_xpaths_called_with_faulty_xpath
50
- assert_raises Nokogiri::XML::XPath::SyntaxError do
51
- xpath_sanitize("<h1>hello<h1>", xpaths: %w(..faulty_xpath))
52
- end
53
- end
54
-
55
- def test_remove_xpaths_called_with_xpath_string
56
- assert_equal "", xpath_sanitize("<a></a>", xpaths: ".//a")
57
- end
58
-
59
- def test_remove_xpaths_called_with_enumerable_xpaths
60
- assert_equal "", xpath_sanitize("<a><span></span></a>", xpaths: %w(.//a .//span))
61
- end
62
-
63
- protected
64
- def xpath_sanitize(input, options = {})
65
- XpathRemovalTestSanitizer.new.sanitize(input, options)
66
- end
67
- end
68
-
69
- module ModuleUnderTest
70
- def module_under_test
71
- self.class.instance_variable_get(:@module_under_test)
72
- end
73
- end
74
-
75
- module FullSanitizerTest
76
- include ModuleUnderTest
77
-
78
- def test_strip_tags_with_quote
79
- input = '<" <img src="trollface.gif" onload="alert(1)"> hi'
80
- result = full_sanitize(input)
81
- acceptable_results = [
82
- # libxml2 >= 2.9.14 and xerces+neko
83
- %{&lt;" hi},
84
- # other libxml2
85
- %{ hi},
86
- ]
87
-
88
- assert_includes(acceptable_results, result)
89
- end
90
-
91
- def test_strip_invalid_html
92
- assert_equal "&lt;&lt;", full_sanitize("<<<bad html")
93
- end
94
-
95
- def test_strip_nested_tags
96
- expected = "Wei&lt;a onclick='alert(document.cookie);'/&gt;rdos"
97
- input = "Wei<<a>a onclick='alert(document.cookie);'</a>/>rdos"
98
- assert_equal expected, full_sanitize(input)
99
- end
100
-
101
- def test_strip_tags_multiline
102
- expected = %{This is a test.\n\n\n\nIt no longer contains any HTML.\n}
103
- input = %{<h1>This is <b>a <a href="" target="_blank">test</a></b>.</h1>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n}
104
-
105
- assert_equal expected, full_sanitize(input)
106
- end
107
-
108
- def test_remove_unclosed_tags
109
- input = "This is <-- not\n a comment here."
110
- result = full_sanitize(input)
111
- acceptable_results = [
112
- # libxml2 >= 2.9.14 and xerces+neko
113
- %{This is &lt;-- not\n a comment here.},
114
- # other libxml2
115
- %{This is },
116
- ]
117
-
118
- assert_includes(acceptable_results, result)
119
- end
120
-
121
- def test_strip_cdata
122
- input = "This has a <![CDATA[<section>]]> here."
123
- result = full_sanitize(input)
124
- acceptable_results = [
125
- # libxml2 = 2.9.14
126
- %{This has a &lt;![CDATA[]]&gt; here.},
127
- # other libxml2
128
- %{This has a ]]&gt; here.},
129
- # xerces+neko
130
- %{This has a here.},
131
- ]
132
-
133
- assert_includes(acceptable_results, result)
134
- end
135
-
136
- def test_strip_blank_string
137
- assert_nil full_sanitize(nil)
138
- assert_equal "", full_sanitize("")
139
- assert_equal " ", full_sanitize(" ")
140
- end
141
-
142
- def test_strip_tags_with_plaintext
143
- assert_equal "Don't touch me", full_sanitize("Don't touch me")
144
- end
145
-
146
- def test_strip_tags_with_tags
147
- assert_equal "This is a test.", full_sanitize("<p>This <u>is<u> a <a href='test.html'><strong>test</strong></a>.</p>")
148
- end
149
-
150
- def test_escape_tags_with_many_open_quotes
151
- assert_equal "&lt;&lt;", full_sanitize("<<<bad html>")
152
- end
153
-
154
- def test_strip_tags_with_sentence
155
- assert_equal "This is a test.", full_sanitize("This is a test.")
156
- end
157
-
158
- def test_strip_tags_with_comment
159
- assert_equal "This has a here.", full_sanitize("This has a <!-- comment --> here.")
160
- end
161
-
162
- def test_strip_tags_with_frozen_string
163
- assert_equal "Frozen string with no tags", full_sanitize("Frozen string with no tags")
164
- end
165
-
166
- def test_full_sanitize_respect_html_escaping_of_the_given_string
167
- assert_equal 'test\r\nstring', full_sanitize('test\r\nstring')
168
- assert_equal "&amp;", full_sanitize("&")
169
- assert_equal "&amp;", full_sanitize("&amp;")
170
- assert_equal "&amp;amp;", full_sanitize("&amp;amp;")
171
- assert_equal "omg &lt;script&gt;BOM&lt;/script&gt;", full_sanitize("omg &lt;script&gt;BOM&lt;/script&gt;")
172
- end
173
-
174
- def test_sanitize_ascii_8bit_string
175
- full_sanitize("<div><a>hello</a></div>".encode("ASCII-8BIT")).tap do |sanitized|
176
- assert_equal "hello", sanitized
177
- assert_equal Encoding::UTF_8, sanitized.encoding
178
- end
179
- end
180
-
181
- protected
182
- def full_sanitize(input, options = {})
183
- module_under_test::FullSanitizer.new.sanitize(input, options)
184
- end
185
- end
186
-
187
- class HTML4FullSanitizerTest < Minitest::Test
188
- @module_under_test = Rails::HTML4
189
- include FullSanitizerTest
190
- end
191
-
192
- class HTML5FullSanitizerTest < Minitest::Test
193
- @module_under_test = Rails::HTML5
194
- include FullSanitizerTest
195
- end if loofah_html5_support?
196
-
197
- module LinkSanitizerTest
198
- include ModuleUnderTest
199
-
200
- def test_strip_links_with_tags_in_tags
201
- expected = "&lt;a href='hello'&gt;all <b>day</b> long&lt;/a&gt;"
202
- input = "<<a>a href='hello'>all <b>day</b> long<</A>/a>"
203
- assert_equal expected, link_sanitize(input)
204
- end
205
-
206
- def test_strip_links_with_unclosed_tags
207
- assert_equal "", link_sanitize("<a<a")
208
- end
209
-
210
- def test_strip_links_with_plaintext
211
- assert_equal "Don't touch me", link_sanitize("Don't touch me")
212
- end
213
-
214
- def test_strip_links_with_line_feed_and_uppercase_tag
215
- assert_equal "on my mind\nall day long", link_sanitize("<a href='almost'>on my mind</a>\n<A href='almost'>all day long</A>")
216
- end
217
-
218
- def test_strip_links_leaves_nonlink_tags
219
- assert_equal "My mind\nall <b>day</b> long", link_sanitize("<a href='almost'>My mind</a>\n<A href='almost'>all <b>day</b> long</A>")
220
- end
221
-
222
- def test_strip_links_with_links
223
- assert_equal "0wn3d", link_sanitize("<a href='http://www.rubyonrails.com/'><a href='http://www.rubyonrails.com/' onlclick='steal()'>0wn3d</a></a>")
224
- end
225
-
226
- def test_strip_links_with_linkception
227
- assert_equal "Magic", link_sanitize("<a href='http://www.rubyonrails.com/'>Mag<a href='http://www.ruby-lang.org/'>ic")
228
- end
229
-
230
- def test_sanitize_ascii_8bit_string
231
- link_sanitize("<div><a>hello</a></div>".encode("ASCII-8BIT")).tap do |sanitized|
232
- assert_equal "<div>hello</div>", sanitized
233
- assert_equal Encoding::UTF_8, sanitized.encoding
234
- end
235
- end
236
-
237
- protected
238
- def link_sanitize(input, options = {})
239
- module_under_test::LinkSanitizer.new.sanitize(input, options)
240
- end
241
- end
242
-
243
- class HTML4LinkSanitizerTest < Minitest::Test
244
- @module_under_test = Rails::HTML4
245
- include LinkSanitizerTest
246
- end
247
-
248
- class HTML5LinkSanitizerTest < Minitest::Test
249
- @module_under_test = Rails::HTML5
250
- include LinkSanitizerTest
251
- end if loofah_html5_support?
252
-
253
- module SafeListSanitizerTest
254
- include ModuleUnderTest
255
-
256
- def test_sanitize_nested_script
257
- assert_equal '&lt;script&gt;alert("XSS");&lt;/script&gt;', safe_list_sanitize('<script><script></script>alert("XSS");<script><</script>/</script><script>script></script>', tags: %w(em))
258
- end
259
-
260
- def test_sanitize_nested_script_in_style
261
- input = '<style><script></style>alert("XSS");<style><</style>/</style><style>script></style>'
262
- result = safe_list_sanitize(input, tags: %w(em))
263
- acceptable_results = [
264
- # libxml2
265
- %{&lt;script&gt;alert("XSS");&lt;/script&gt;},
266
- # xerces+neko. unavoidable double-escaping, see loofah/docs/2022-10-decision-on-cdata-nodes.md
267
- %{&amp;lt;script&amp;gt;alert(\"XSS\");&amp;lt;&amp;lt;/style&amp;gt;/script&amp;gt;},
268
- ]
269
-
270
- assert_includes(acceptable_results, result)
271
- end
272
-
273
- def test_strip_unclosed_cdata
274
- input = "This has an unclosed <![CDATA[<section>]] here..."
275
-
276
- result = safe_list_sanitize(input)
277
-
278
- acceptable_results = [
279
- # libxml2 = 2.9.14
280
- %{This has an unclosed &lt;![CDATA[]] here...},
281
- # other libxml2
282
- %{This has an unclosed ]] here...},
283
- # xerces+neko
284
- %{This has an unclosed }
285
- ]
286
-
287
- assert_includes(acceptable_results, result)
288
- end
289
-
290
- def test_sanitize_form
291
- assert_sanitized "<form action=\"/foo/bar\" method=\"post\"><input></form>", ""
292
- end
293
-
294
- def test_sanitize_plaintext
295
- # note that the `plaintext` tag has been deprecated since HTML 2
296
- # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/plaintext
297
- input = "<plaintext><span>foo</span></plaintext>"
298
- result = safe_list_sanitize(input)
299
- acceptable_results = [
300
- # libxml2
301
- "<span>foo</span>",
302
- # xerces+nekohtml-unit
303
- "&lt;span&gt;foo&lt;/span&gt;&lt;/plaintext&gt;",
304
- # xerces+cyberneko
305
- "&lt;span&gt;foo&lt;/span&gt;"
306
- ]
307
-
308
- assert_includes(acceptable_results, result)
309
- end
310
-
311
- def test_sanitize_script
312
- assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cblah blah blahd e f"
313
- end
314
-
315
- def test_sanitize_js_handlers
316
- raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>}
317
- assert_sanitized raw, %{onthis="do that" <a href="#" name="foo">hello</a>}
318
- end
319
-
320
- def test_sanitize_javascript_href
321
- raw = %{href="javascript:bang" <a href="javascript:bang" name="hello">foo</a>, <span href="javascript:bang">bar</span>}
322
- assert_sanitized raw, %{href="javascript:bang" <a name="hello">foo</a>, <span>bar</span>}
323
- end
324
-
325
- def test_sanitize_image_src
326
- raw = %{src="javascript:bang" <img src="javascript:bang" width="5">foo</img>, <span src="javascript:bang">bar</span>}
327
- assert_sanitized raw, %{src="javascript:bang" <img width="5">foo, <span>bar</span>}
328
- end
329
-
330
- def test_should_allow_anchors
331
- assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>), %(<a href=\"foo\">baz</a>)
332
- end
333
-
334
- def test_video_poster_sanitization
335
- scope_allowed_tags(%w(video)) do
336
- scope_allowed_attributes %w(src poster) do
337
- expected = if RUBY_PLATFORM == "java"
338
- # xerces+nekohtml alphabetizes the attributes! FML.
339
- %(<video poster="posterimage.jpg" src="videofile.ogg"></video>)
340
- else
341
- %(<video src="videofile.ogg" poster="posterimage.jpg"></video>)
342
- end
343
- assert_sanitized(
344
- %(<video src="videofile.ogg" autoplay poster="posterimage.jpg"></video>),
345
- expected,
346
- )
347
- assert_sanitized(
348
- %(<video src="videofile.ogg" poster=javascript:alert(1)></video>),
349
- %(<video src="videofile.ogg"></video>),
350
- )
351
- end
352
- end
353
- end
354
-
355
- # RFC 3986, sec 4.2
356
- def test_allow_colons_in_path_component
357
- assert_sanitized "<a href=\"./this:that\">foo</a>"
358
- end
359
-
360
- %w(src width height alt).each do |img_attr|
361
- define_method "test_should_allow_image_#{img_attr}_attribute" do
362
- assert_sanitized %(<img #{img_attr}="foo" onclick="bar" />), %(<img #{img_attr}="foo">)
363
- end
364
- end
365
-
366
- def test_lang_and_xml_lang
367
- # https://html.spec.whatwg.org/multipage/dom.html#the-lang-and-xml:lang-attributes
368
- #
369
- # 3.2.6.2 The lang and xml:lang attributes
370
- #
371
- # ... Authors must not use the lang attribute in the XML namespace on HTML elements in HTML
372
- # documents. To ease migration to and from XML, authors may specify an attribute in no namespace
373
- # with no prefix and with the literal localname "xml:lang" on HTML elements in HTML documents,
374
- # but such attributes must only be specified if a lang attribute in no namespace is also
375
- # specified, and both attributes must have the same value when compared in an ASCII
376
- # case-insensitive manner.
377
- input = expected = "<div lang=\"en\" xml:lang=\"en\">foo</div>"
378
- assert_sanitized(input, expected)
379
- end
380
-
381
- def test_should_handle_non_html
382
- assert_sanitized "abc"
383
- end
384
-
385
- def test_should_handle_blank_text
386
- assert_nil(safe_list_sanitize(nil))
387
- assert_equal("", safe_list_sanitize(""))
388
- assert_equal(" ", safe_list_sanitize(" "))
389
- end
390
-
391
- def test_setting_allowed_tags_affects_sanitization
392
- scope_allowed_tags %w(u) do |sanitizer|
393
- assert_equal "<u></u>", sanitizer.sanitize("<a><u></u></a>")
394
- end
395
- end
396
-
397
- def test_setting_allowed_attributes_affects_sanitization
398
- scope_allowed_attributes %w(foo) do |sanitizer|
399
- input = '<a foo="hello" bar="world"></a>'
400
- assert_equal '<a foo="hello"></a>', sanitizer.sanitize(input)
401
- end
402
- end
403
-
404
- def test_custom_tags_overrides_allowed_tags
405
- scope_allowed_tags %(u) do |sanitizer|
406
- input = "<a><u></u></a>"
407
- assert_equal "<a></a>", sanitizer.sanitize(input, tags: %w(a))
408
- end
409
- end
410
-
411
- def test_custom_attributes_overrides_allowed_attributes
412
- scope_allowed_attributes %(foo) do |sanitizer|
413
- input = '<a foo="hello" bar="world"></a>'
414
- assert_equal '<a bar="world"></a>', sanitizer.sanitize(input, attributes: %w(bar))
415
- end
416
- end
417
-
418
- def test_should_allow_prune
419
- sanitizer = module_under_test::SafeListSanitizer.new(prune: true)
420
- text = "<u>leave me <b>now</b></u>"
421
- assert_equal "<u>leave me </u>", sanitizer.sanitize(text, tags: %w(u))
422
- end
423
-
424
- def test_should_allow_custom_tags
425
- text = "<u>foo</u>"
426
- assert_equal text, safe_list_sanitize(text, tags: %w(u))
427
- end
428
-
429
- def test_should_allow_only_custom_tags
430
- text = "<u>foo</u> with <i>bar</i>"
431
- assert_equal "<u>foo</u> with bar", safe_list_sanitize(text, tags: %w(u))
432
- end
433
-
434
- def test_should_allow_custom_tags_with_attributes
435
- text = %(<blockquote cite="http://example.com/">foo</blockquote>)
436
- assert_equal text, safe_list_sanitize(text)
437
- end
438
-
439
- def test_should_allow_custom_tags_with_custom_attributes
440
- text = %(<blockquote foo="bar">Lorem ipsum</blockquote>)
441
- assert_equal text, safe_list_sanitize(text, attributes: ["foo"])
442
- end
443
-
444
- def test_scrub_style_if_style_attribute_option_is_passed
445
- input = '<p style="color: #000; background-image: url(http://www.ragingplatypus.com/i/cam-full.jpg);"></p>'
446
- actual = safe_list_sanitize(input, attributes: %w(style))
447
-
448
- assert_includes(['<p style="color: #000;"></p>', '<p style="color:#000;"></p>'], actual)
449
- end
450
-
451
- def test_should_raise_argument_error_if_tags_is_not_enumerable
452
- assert_raises ArgumentError do
453
- safe_list_sanitize("<a>some html</a>", tags: "foo")
454
- end
455
- end
456
-
457
- def test_should_raise_argument_error_if_attributes_is_not_enumerable
458
- assert_raises ArgumentError do
459
- safe_list_sanitize("<a>some html</a>", attributes: "foo")
460
- end
461
- end
462
-
463
- def test_should_not_accept_non_loofah_inheriting_scrubber
464
- scrubber = Object.new
465
- def scrubber.scrub(node); node.name = "h1"; end
466
-
467
- assert_raises Loofah::ScrubberNotFound do
468
- safe_list_sanitize("<a>some html</a>", scrubber: scrubber)
469
- end
470
- end
471
-
472
- def test_should_accept_loofah_inheriting_scrubber
473
- scrubber = Loofah::Scrubber.new
474
- def scrubber.scrub(node); node.replace("<h1>#{node.inner_html}</h1>"); end
475
-
476
- html = "<script>hello!</script>"
477
- assert_equal "<h1>hello!</h1>", safe_list_sanitize(html, scrubber: scrubber)
478
- end
479
-
480
- def test_should_accept_loofah_scrubber_that_wraps_a_block
481
- scrubber = Loofah::Scrubber.new { |node| node.replace("<h1>#{node.inner_html}</h1>") }
482
- html = "<script>hello!</script>"
483
- assert_equal "<h1>hello!</h1>", safe_list_sanitize(html, scrubber: scrubber)
484
- end
485
-
486
- def test_custom_scrubber_takes_precedence_over_other_options
487
- scrubber = Loofah::Scrubber.new { |node| node.replace("<h1>#{node.inner_html}</h1>") }
488
- html = "<script>hello!</script>"
489
- assert_equal "<h1>hello!</h1>", safe_list_sanitize(html, scrubber: scrubber, tags: ["foo"])
490
- end
491
-
492
- def test_should_strip_src_attribute_in_img_with_bad_protocols
493
- assert_sanitized %(<img src="javascript:bang" title="1">), %(<img title="1">)
494
- end
495
-
496
- def test_should_strip_href_attribute_in_a_with_bad_protocols
497
- assert_sanitized %(<a href="javascript:bang" title="1">boo</a>), %(<a title="1">boo</a>)
498
- end
499
-
500
- def test_should_block_script_tag
501
- assert_sanitized %(<SCRIPT\nSRC=http://ha.ckers.org/xss.js></SCRIPT>), ""
502
- end
503
-
504
- def test_should_not_fall_for_xss_image_hack_with_uppercase_tags
505
- assert_sanitized %(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">), %(<img>alert("XSS")"&gt;)
506
- end
507
-
508
- [%(<IMG SRC="javascript:alert('XSS');">),
509
- %(<IMG SRC=javascript:alert('XSS')>),
510
- %(<IMG SRC=JaVaScRiPt:alert('XSS')>),
511
- %(<IMG SRC=javascript:alert(&quot;XSS&quot;)>),
512
- %(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>),
513
- %(<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>),
514
- %(<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>),
515
- %(<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>),
516
- %(<IMG SRC="jav\tascript:alert('XSS');">),
517
- %(<IMG SRC="jav&#x09;ascript:alert('XSS');">),
518
- %(<IMG SRC="jav&#x0A;ascript:alert('XSS');">),
519
- %(<IMG SRC="jav&#x0D;ascript:alert('XSS');">),
520
- %(<IMG SRC=" &#14; javascript:alert('XSS');">),
521
- %(<IMG SRC="javascript&#x3a;alert('XSS');">),
522
- %(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each do |img_hack|
523
- define_method "test_should_not_fall_for_xss_image_hack_#{img_hack}" do
524
- assert_sanitized img_hack, "<img>"
525
- end
526
- end
527
-
528
- def test_should_sanitize_tag_broken_up_by_null
529
- input = %(<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>)
530
- result = safe_list_sanitize(input)
531
- acceptable_results = [
532
- # libxml2
533
- "",
534
- # xerces+neko
535
- 'alert("XSS")',
536
- ]
537
-
538
- assert_includes(acceptable_results, result)
539
- end
540
-
541
- def test_should_sanitize_invalid_script_tag
542
- assert_sanitized %(<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>), ""
543
- end
544
-
545
- def test_should_sanitize_script_tag_with_multiple_open_brackets
546
- assert_sanitized %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "&lt;alert(\"XSS\");//&lt;"
547
- end
548
-
549
- def test_should_sanitize_script_tag_with_multiple_open_brackets_2
550
- input = %(<iframe src=http://ha.ckers.org/scriptlet.html\n<a)
551
- result = safe_list_sanitize(input)
552
- acceptable_results = [
553
- # libxml2
554
- "",
555
- # xerces+neko
556
- "&lt;a",
557
- ]
558
-
559
- assert_includes(acceptable_results, result)
560
- end
561
-
562
- def test_should_sanitize_unclosed_script
563
- assert_sanitized %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), ""
564
- end
565
-
566
- def test_should_sanitize_half_open_scripts
567
- input = %(<IMG SRC="javascript:alert('XSS')")
568
- result = safe_list_sanitize(input)
569
- acceptable_results = [
570
- # libxml2
571
- "<img>",
572
- # libgumbo
573
- "",
574
- ]
575
-
576
- assert_includes(acceptable_results, result)
577
- end
578
-
579
- def test_should_not_fall_for_ridiculous_hack
580
- img_hack = %(<IMG\nSRC\n=\n"\nj\na\nv\na\ns\nc\nr\ni\np\nt\n:\na\nl\ne\nr\nt\n(\n'\nX\nS\nS\n'\n)\n"\n>)
581
- assert_sanitized img_hack, "<img>"
582
- end
583
-
584
- def test_should_sanitize_attributes
585
- input = %(<SPAN title="'><script>alert()</script>">blah</SPAN>)
586
- result = safe_list_sanitize(input)
587
- acceptable_results = [
588
- # libxml2
589
- %(<span title="'&gt;&lt;script&gt;alert()&lt;/script&gt;">blah</span>),
590
- # libgumbo
591
- # this looks scary, but it's fine. for a more detailed analysis check out:
592
- # https://github.com/discourse/discourse/pull/21522#issuecomment-1545697968
593
- %(<span title="'><script>alert()</script>">blah</span>)
594
- ]
595
-
596
- assert_includes(acceptable_results, result)
597
- end
598
-
599
- def test_should_sanitize_invalid_tag_names
600
- assert_sanitized(%(a b c<script/XSS src="http://ha.ckers.org/xss.js"></script>d e f), "a b cd e f")
601
- end
602
-
603
- def test_should_sanitize_non_alpha_and_non_digit_characters_in_tags
604
- assert_sanitized('<a onclick!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>foo</a>', "<a>foo</a>")
605
- end
606
-
607
- def test_should_sanitize_invalid_tag_names_in_single_tags
608
- input = %(<img/src="http://ha.ckers.org/xss.js"/>)
609
- result = safe_list_sanitize(input)
610
- acceptable_results = [
611
- # libxml2
612
- "<img>",
613
- # libgumbo
614
- %(<img src="http://ha.ckers.org/xss.js">),
615
- ]
616
-
617
- assert_includes(acceptable_results, result)
618
- end
619
-
620
- def test_should_sanitize_img_dynsrc_lowsrc
621
- assert_sanitized(%(<img lowsrc="javascript:alert('XSS')" />), "<img>")
622
- end
623
-
624
- def test_should_sanitize_img_vbscript
625
- assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), "<img>"
626
- end
627
-
628
- def test_should_sanitize_cdata_section
629
- input = "<![CDATA[<span>section</span>]]>"
630
- result = safe_list_sanitize(input)
631
- acceptable_results = [
632
- # libxml2 = 2.9.14
633
- %{&lt;![CDATA[<span>section</span>]]&gt;},
634
- # other libxml2
635
- %{section]]&gt;},
636
- # xerces+neko
637
- "",
638
- ]
639
-
640
- assert_includes(acceptable_results, result)
641
- end
642
-
643
- def test_should_sanitize_unterminated_cdata_section
644
- input = "<![CDATA[<span>neverending..."
645
- result = safe_list_sanitize(input)
646
-
647
- acceptable_results = [
648
- # libxml2 = 2.9.14
649
- %{&lt;![CDATA[<span>neverending...</span>},
650
- # other libxml2
651
- %{neverending...},
652
- # xerces+neko
653
- ""
654
- ]
655
-
656
- assert_includes(acceptable_results, result)
657
- end
658
-
659
- def test_should_not_mangle_urls_with_ampersand
660
- assert_sanitized %{<a href=\"http://www.domain.com?var1=1&amp;var2=2\">my link</a>}
661
- end
662
-
663
- def test_should_sanitize_neverending_attribute
664
- # note that assert_dom_equal chokes in this case! so avoid using assert_sanitized
665
- assert_equal("<span class=\"\\\"></span>", safe_list_sanitize("<span class=\"\\\">"))
666
- end
667
-
668
- [
669
- %(<a href="javascript&#x3a;alert('XSS');">),
670
- %(<a href="javascript&#x003a;alert('XSS');">),
671
- %(<a href="javascript&#x3A;alert('XSS');">),
672
- %(<a href="javascript&#x003A;alert('XSS');">)
673
- ].each_with_index do |enc_hack, i|
674
- define_method "test_x03a_handling_#{i + 1}" do
675
- assert_sanitized enc_hack, "<a></a>"
676
- end
677
- end
678
-
679
- def test_x03a_legitimate
680
- assert_sanitized %(<a href="http&#x3a;//legit">asdf</a>), %(<a href="http://legit">asdf</a>)
681
- assert_sanitized %(<a href="http&#x3A;//legit">asdf</a>), %(<a href="http://legit">asdf</a>)
682
- end
683
-
684
- def test_sanitize_ascii_8bit_string
685
- safe_list_sanitize("<div><a>hello</a></div>".encode("ASCII-8BIT")).tap do |sanitized|
686
- assert_equal "<div><a>hello</a></div>", sanitized
687
- assert_equal Encoding::UTF_8, sanitized.encoding
688
- end
689
- end
690
-
691
- def test_sanitize_data_attributes
692
- assert_sanitized %(<a href="/blah" data-method="post">foo</a>), %(<a href="/blah">foo</a>)
693
- assert_sanitized %(<a data-remote="true" data-type="script" data-method="get" data-cross-domain="true" href="attack.js">Launch the missiles</a>), %(<a href="attack.js">Launch the missiles</a>)
694
- end
695
-
696
- def test_allow_data_attribute_if_requested
697
- text = %(<a data-foo="foo">foo</a>)
698
- assert_equal %(<a data-foo="foo">foo</a>), safe_list_sanitize(text, attributes: ["data-foo"])
699
- end
700
-
701
- # https://developer.mozilla.org/en-US/docs/Glossary/Void_element
702
- VOID_ELEMENTS = %w[area base br col embed hr img input keygen link meta param source track wbr]
703
-
704
- %w(strong em b i p code pre tt samp kbd var sub
705
- sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr
706
- acronym a img blockquote del ins time).each do |tag_name|
707
- define_method "test_default_safelist_should_allow_#{tag_name}" do
708
- if VOID_ELEMENTS.include?(tag_name)
709
- assert_sanitized("<#{tag_name}>")
710
- else
711
- assert_sanitized("<#{tag_name}>foo</#{tag_name}>")
712
- end
713
- end
714
- end
715
-
716
- def test_datetime_attribute
717
- assert_sanitized("<time datetime=\"2023-01-01\">Today</time>")
718
- end
719
-
720
- def test_abbr_attribute
721
- scope_allowed_tags(%w(table tr th td)) do
722
- assert_sanitized(%(<table><tr><td abbr="UK">United Kingdom</td></tr></table>))
723
- end
724
- end
725
-
726
- def test_uri_escaping_of_href_attr_in_a_tag_in_safe_list_sanitizer
727
- html = %{<a href='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
728
-
729
- text = safe_list_sanitize(html)
730
-
731
- acceptable_results = [
732
- # nokogiri's vendored+patched libxml2 (0002-Update-entities-to-remove-handling-of-ssi.patch)
733
- %{<a href="examp&lt;!--%22%20unsafeattr=foo()&gt;--&gt;le.com">test</a>},
734
- # system libxml2
735
- %{<a href="examp<!--%22%20unsafeattr=foo()>-->le.com">test</a>},
736
- # xerces+neko
737
- %{<a href="examp&lt;!--%22 unsafeattr=foo()&gt;--&gt;le.com">test</a>}
738
- ]
739
-
740
- assert_includes(acceptable_results, text)
741
- end
742
-
743
- def test_uri_escaping_of_src_attr_in_a_tag_in_safe_list_sanitizer
744
- html = %{<a src='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
745
-
746
- text = safe_list_sanitize(html)
747
-
748
- acceptable_results = [
749
- # nokogiri's vendored+patched libxml2 (0002-Update-entities-to-remove-handling-of-ssi.patch)
750
- %{<a src="examp&lt;!--%22%20unsafeattr=foo()&gt;--&gt;le.com">test</a>},
751
- # system libxml2
752
- %{<a src="examp<!--%22%20unsafeattr=foo()>-->le.com">test</a>},
753
- # xerces+neko
754
- %{<a src="examp&lt;!--%22 unsafeattr=foo()&gt;--&gt;le.com">test</a>}
755
- ]
756
-
757
- assert_includes(acceptable_results, text)
758
- end
759
-
760
- def test_uri_escaping_of_name_attr_in_a_tag_in_safe_list_sanitizer
761
- html = %{<a name='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
762
-
763
- text = safe_list_sanitize(html)
764
-
765
- acceptable_results = [
766
- # nokogiri's vendored+patched libxml2 (0002-Update-entities-to-remove-handling-of-ssi.patch)
767
- %{<a name="examp&lt;!--%22%20unsafeattr=foo()&gt;--&gt;le.com">test</a>},
768
- # system libxml2
769
- %{<a name="examp<!--%22%20unsafeattr=foo()>-->le.com">test</a>},
770
- # xerces+neko
771
- %{<a name="examp&lt;!--%22 unsafeattr=foo()&gt;--&gt;le.com">test</a>}
772
- ]
773
-
774
- assert_includes(acceptable_results, text)
775
- end
776
-
777
- def test_uri_escaping_of_name_action_in_a_tag_in_safe_list_sanitizer
778
- html = %{<a action='examp<!--" unsafeattr=foo()>-->le.com'>test</a>}
779
-
780
- text = safe_list_sanitize(html, attributes: ["action"])
781
-
782
- acceptable_results = [
783
- # nokogiri's vendored+patched libxml2 (0002-Update-entities-to-remove-handling-of-ssi.patch)
784
- %{<a action="examp&lt;!--%22%20unsafeattr=foo()&gt;--&gt;le.com">test</a>},
785
- # system libxml2
786
- %{<a action="examp<!--%22%20unsafeattr=foo()>-->le.com">test</a>},
787
- # xerces+neko
788
- %{<a action="examp&lt;!--%22 unsafeattr=foo()&gt;--&gt;le.com">test</a>},
789
- ]
790
-
791
- assert_includes(acceptable_results, text)
792
- end
793
-
794
- def test_exclude_node_type_processing_instructions
795
- input = "<div>text</div><?div content><b>text</b>"
796
- result = safe_list_sanitize(input)
797
- acceptable_results = [
798
- # jruby cyberneko (nokogiri < 1.14.0)
799
- "<div>text</div>",
800
- # everything else
801
- "<div>text</div><b>text</b>",
802
- ]
803
-
804
- assert_includes(acceptable_results, result)
805
- end
806
-
807
- def test_exclude_node_type_comment
808
- assert_equal("<div>text</div><b>text</b>", safe_list_sanitize("<div>text</div><!-- comment --><b>text</b>"))
809
- end
810
-
811
- %w[text/plain text/css image/png image/gif image/jpeg].each do |mediatype|
812
- define_method "test_mediatype_#{mediatype}_allowed" do
813
- input = %Q(<img src="data:#{mediatype};base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
814
- expected = input
815
- actual = safe_list_sanitize(input)
816
- assert_equal(expected, actual)
817
-
818
- input = %Q(<img src="DATA:#{mediatype};base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">)
819
- expected = input
820
- actual = safe_list_sanitize(input)
821
- assert_equal(expected, actual)
822
- end
823
- end
824
-
825
- def test_mediatype_text_html_disallowed
826
- input = '<img src="data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">'
827
- expected = "<img>"
828
- actual = safe_list_sanitize(input)
829
- assert_equal(expected, actual)
830
-
831
- input = '<img src="DATA:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">'
832
- expected = "<img>"
833
- actual = safe_list_sanitize(input)
834
- assert_equal(expected, actual)
835
- end
836
-
837
- def test_mediatype_image_svg_xml_disallowed
838
- input = '<img src="data:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">'
839
- expected = "<img>"
840
- actual = safe_list_sanitize(input)
841
- assert_equal(expected, actual)
842
-
843
- input = '<img src="DATA:image/svg+xml;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">'
844
- expected = "<img>"
845
- actual = safe_list_sanitize(input)
846
- assert_equal(expected, actual)
847
- end
848
-
849
- def test_mediatype_other_disallowed
850
- input = '<a href="data:foo;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">foo</a>'
851
- expected = "<a>foo</a>"
852
- actual = safe_list_sanitize(input)
853
- assert_equal(expected, actual)
854
-
855
- input = '<a href="DATA:foo;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4=">foo</a>'
856
- expected = "<a>foo</a>"
857
- actual = safe_list_sanitize(input)
858
- assert_equal(expected, actual)
859
- end
860
-
861
- def test_scrubbing_svg_attr_values_that_allow_ref
862
- input = '<div fill="yellow url(http://bad.com/) #fff">hey</div>'
863
- expected = '<div fill="yellow #fff">hey</div>'
864
- actual = scope_allowed_attributes %w(fill) do
865
- safe_list_sanitize(input)
866
- end
867
-
868
- assert_equal(expected, actual)
869
- end
870
-
871
- def test_style_with_css_payload
872
- input, tags = "<style>div > span { background: \"red\"; }</style>", ["style"]
873
- actual = safe_list_sanitize(input, tags: tags)
874
- acceptable_results = [
875
- # libxml2
876
- "<style>div &gt; span { background: \"red\"; }</style>",
877
- # libgumbo
878
- "<style>div > span { background: \"red\"; }</style>",
879
- ]
880
-
881
- assert_includes(acceptable_results, actual)
882
- end
883
-
884
- def test_combination_of_select_and_style_with_css_payload
885
- input, tags = "<select><style>div > span { background: \"red\"; }</style></select>", ["select", "style"]
886
- actual = safe_list_sanitize(input, tags: tags)
887
- acceptable_results = [
888
- # libxml2
889
- "<select><style>div &gt; span { background: \"red\"; }</style></select>",
890
- # libgumbo
891
- "<select>div &gt; span { background: \"red\"; }</select>",
892
- ]
893
-
894
- assert_includes(acceptable_results, actual)
895
- end
896
-
897
- def test_combination_of_select_and_style_with_script_payload
898
- input, tags = "<select><style><script>alert(1)</script></style></select>", ["select", "style"]
899
- actual = safe_list_sanitize(input, tags: tags)
900
- acceptable_results = [
901
- # libxml2
902
- "<select><style>&lt;script&gt;alert(1)&lt;/script&gt;</style></select>",
903
- # libgumbo
904
- "<select>alert(1)</select>",
905
- ]
906
-
907
- assert_includes(acceptable_results, actual)
908
- end
909
-
910
- def test_combination_of_svg_and_style_with_script_payload
911
- input, tags = "<svg><style><script>alert(1)</script></style></svg>", ["svg", "style"]
912
- actual = safe_list_sanitize(input, tags: tags)
913
- acceptable_results = [
914
- # libxml2
915
- "<svg><style>&lt;script&gt;alert(1)&lt;/script&gt;</style></svg>",
916
- # libgumbo
917
- "<svg><style></style></svg>",
918
- ]
919
-
920
- assert_includes(acceptable_results, actual)
921
- end
922
-
923
- def test_combination_of_math_and_style_with_img_payload
924
- input, tags = "<math><style><img src=x onerror=alert(1)></style></math>", ["math", "style"]
925
- actual = safe_list_sanitize(input, tags: tags)
926
- acceptable_results = [
927
- # libxml2
928
- "<math><style>&lt;img src=x onerror=alert(1)&gt;</style></math>",
929
- # libgumbo
930
- "<math><style></style></math>",
931
- ]
932
-
933
- assert_includes(acceptable_results, actual)
934
- end
935
-
936
- def test_combination_of_math_and_style_with_img_payload_2
937
- input, tags = "<math><style><img src=x onerror=alert(1)></style></math>", ["math", "style", "img"]
938
- actual = safe_list_sanitize(input, tags: tags)
939
- acceptable_results = [
940
- # libxml2
941
- "<math><style>&lt;img src=x onerror=alert(1)&gt;</style></math>",
942
- # libgumbo
943
- "<math><style></style></math><img src=\"x\">",
944
- ]
945
-
946
- assert_includes(acceptable_results, actual)
947
- end
948
-
949
- def test_combination_of_svg_and_style_with_img_payload
950
- input, tags = "<svg><style><img src=x onerror=alert(1)></style></svg>", ["svg", "style"]
951
- actual = safe_list_sanitize(input, tags: tags)
952
- acceptable_results = [
953
- # libxml2
954
- "<svg><style>&lt;img src=x onerror=alert(1)&gt;</style></svg>",
955
- # libgumbo
956
- "<svg><style></style></svg>",
957
- ]
958
-
959
- assert_includes(acceptable_results, actual)
960
- end
961
-
962
- def test_combination_of_svg_and_style_with_img_payload_2
963
- input, tags = "<svg><style><img src=x onerror=alert(1)></style></svg>", ["svg", "style", "img"]
964
- actual = safe_list_sanitize(input, tags: tags)
965
- acceptable_results = [
966
- # libxml2
967
- "<svg><style>&lt;img src=x onerror=alert(1)&gt;</style></svg>",
968
- # libgumbo
969
- "<svg><style></style></svg><img src=\"x\">",
970
- ]
971
-
972
- assert_includes(acceptable_results, actual)
973
- end
974
-
975
- def test_combination_of_svg_and_style_with_escaped_img_payload
976
- # https://hackerone.com/reports/2503220
977
- input, tags = "<svg><style>&lt;img src onerror=alert(1)>", ["svg", "style"]
978
- actual = safe_list_sanitize(input, tags: tags)
979
- acceptable_results = [
980
- # libxml2
981
- "<svg><style>&amp;lt;img src onerror=alert(1)&gt;</style></svg>",
982
- # libgumbo
983
- "<svg><style>&lt;img src onerror=alert(1)&gt;</style></svg>",
984
- ]
985
-
986
- assert_includes(acceptable_results, actual)
987
- end
988
-
989
- def test_combination_of_math_and_style_with_escaped_img_payload
990
- # https://hackerone.com/reports/2503220
991
- input, tags = "<math><style>&lt;img src onerror=alert(1)>", ["math", "style"]
992
- actual = safe_list_sanitize(input, tags: tags)
993
- acceptable_results = [
994
- # libxml2
995
- "<math><style>&amp;lt;img src onerror=alert(1)&gt;</style></math>",
996
- # libgumbo
997
- "<math><style>&lt;img src onerror=alert(1)&gt;</style></math>",
998
- ]
999
-
1000
- assert_includes(acceptable_results, actual)
1001
- end
1002
-
1003
- def test_combination_of_style_and_disallowed_svg_with_script_payload
1004
- # https://hackerone.com/reports/2519936
1005
- input, tags = "<svg><style><style class='</style><script>alert(1)</script>'>", ["style"]
1006
- actual = safe_list_sanitize(input, tags: tags)
1007
- acceptable_results = [
1008
- # libxml2
1009
- "<style>&lt;style class='</style>alert(1)'&gt;",
1010
- # libgumbo
1011
- "",
1012
- ]
1013
-
1014
- assert_includes(acceptable_results, actual)
1015
- end
1016
-
1017
- def test_combination_of_style_and_disallowed_math_with_script_payload
1018
- # https://hackerone.com/reports/2519936
1019
- input, tags = "<math><style><style class='</style><script>alert(1)</script>'>", ["style"]
1020
- actual = safe_list_sanitize(input, tags: tags)
1021
- acceptable_results = [
1022
- # libxml2
1023
- "<style>&lt;style class='</style>alert(1)'&gt;",
1024
- # libgumbo
1025
- "",
1026
- ]
1027
-
1028
- assert_includes(acceptable_results, actual)
1029
- end
1030
-
1031
- def test_math_with_disallowed_mtext_and_img_payload
1032
- # https://hackerone.com/reports/2519941
1033
- input, tags = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>", ["math", "style"]
1034
- actual = safe_list_sanitize(input, tags: tags)
1035
- acceptable_results = [
1036
- # libxml2
1037
- "<math><style>&lt;img src=: onerror=alert(1)&gt;</style></math>",
1038
- # libgumbo
1039
- "<math></math>",
1040
- ]
1041
-
1042
- assert_includes(acceptable_results, actual)
1043
- end
1044
-
1045
- def test_should_sanitize_illegal_style_properties
1046
- raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;)
1047
- expected = %(display:block;width:100%;height:100%;background-color:black;background-x:center;background-y:center;)
1048
- assert_equal expected, sanitize_css(raw)
1049
- end
1050
-
1051
- def test_should_sanitize_with_trailing_space
1052
- raw = "display:block; "
1053
- expected = "display:block;"
1054
- assert_equal expected, sanitize_css(raw)
1055
- end
1056
-
1057
- def test_should_sanitize_xul_style_attributes
1058
- raw = %(-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss'))
1059
- assert_equal "", sanitize_css(raw)
1060
- end
1061
-
1062
- def test_should_sanitize_div_background_image_unicode_encoded
1063
- [
1064
- convert_to_css_hex("url(javascript:alert(1))", false),
1065
- convert_to_css_hex("url(javascript:alert(1))", true),
1066
- convert_to_css_hex("url(https://example.com)", false),
1067
- convert_to_css_hex("url(https://example.com)", true),
1068
- ].each do |propval|
1069
- raw = "background-image:" + propval
1070
- assert_empty(sanitize_css(raw))
1071
- end
1072
- end
1073
-
1074
- def test_should_allow_div_background_image_unicode_encoded_safe_functions
1075
- [
1076
- convert_to_css_hex("rgb(255,0,0)", false),
1077
- convert_to_css_hex("rgb(255,0,0)", true),
1078
- ].each do |propval|
1079
- raw = "background-image:" + propval
1080
-
1081
- assert_includes(sanitize_css(raw), "background-image")
1082
- end
1083
- end
1084
-
1085
- def test_should_sanitize_div_style_expression
1086
- raw = %(width: expression(alert('XSS'));)
1087
- assert_equal "", sanitize_css(raw)
1088
- end
1089
-
1090
- def test_should_sanitize_across_newlines
1091
- raw = %(\nwidth:\nexpression(alert('XSS'));\n)
1092
- assert_equal "", sanitize_css(raw)
1093
- end
1094
-
1095
- def test_should_prune_mglyph
1096
- # https://hackerone.com/reports/2519936
1097
- input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
1098
- tags = %w(math mtext table mglyph style).freeze
1099
-
1100
- actual = nil
1101
- assert_output(nil, /WARNING: 'mglyph' tags cannot be allowed by the PermitScrubber/) do
1102
- actual = safe_list_sanitize(input, tags: tags)
1103
- end
1104
-
1105
- acceptable_results = [
1106
- # libxml2
1107
- "<math><mtext><table><style>&lt;img src=: onerror=alert(1)&gt;</style></table></mtext></math>",
1108
- # libgumbo
1109
- "<math><mtext><style><img src=: onerror=alert(1)></style><table></table></mtext></math>",
1110
- ]
1111
-
1112
- assert_includes(acceptable_results, actual)
1113
- end
1114
-
1115
- def test_should_prune_malignmark
1116
- # https://hackerone.com/reports/2519936
1117
- input = "<math><mtext><table><malignmark><style><img src=: onerror=alert(1)>"
1118
- tags = %w(math mtext table malignmark style).freeze
1119
-
1120
- actual = nil
1121
- assert_output(nil, /WARNING: 'malignmark' tags cannot be allowed by the PermitScrubber/) do
1122
- actual = safe_list_sanitize(input, tags: tags)
1123
- end
1124
-
1125
- acceptable_results = [
1126
- # libxml2
1127
- "<math><mtext><table><style>&lt;img src=: onerror=alert(1)&gt;</style></table></mtext></math>",
1128
- # libgumbo
1129
- "<math><mtext><style><img src=: onerror=alert(1)></style><table></table></mtext></math>",
1130
- ]
1131
-
1132
- assert_includes(acceptable_results, actual)
1133
- end
1134
-
1135
- def test_should_prune_noscript
1136
- # https://hackerone.com/reports/2509647
1137
- input = "<div><noscript><p id='</noscript><script>alert(1)</script>'></noscript>"
1138
- tags = ["p", "div", "noscript"].freeze
1139
-
1140
- actual = nil
1141
- assert_output(nil, /WARNING: 'noscript' tags cannot be allowed by the PermitScrubber/) do
1142
- actual = safe_list_sanitize(input, tags: tags, attributes: %w(id))
1143
- end
1144
-
1145
- acceptable_results = [
1146
- # libxml2
1147
- "<div><p id=\"&lt;/noscript&gt;&lt;script&gt;alert(1)&lt;/script&gt;\"></p></div>",
1148
- # libgumbo
1149
- "<div><p id=\"</noscript><script>alert(1)</script>\"></p></div>",
1150
- ]
1151
-
1152
- assert_includes(acceptable_results, actual)
1153
- end
1154
-
1155
- protected
1156
- def safe_list_sanitize(input, options = {})
1157
- module_under_test::SafeListSanitizer.new.sanitize(input, options)
1158
- end
1159
-
1160
- def assert_sanitized(input, expected = nil)
1161
- assert_equal((expected || input), safe_list_sanitize(input))
1162
- end
1163
-
1164
- def scope_allowed_tags(tags)
1165
- old_tags = module_under_test::SafeListSanitizer.allowed_tags
1166
- module_under_test::SafeListSanitizer.allowed_tags = tags
1167
- yield module_under_test::SafeListSanitizer.new
1168
- ensure
1169
- module_under_test::SafeListSanitizer.allowed_tags = old_tags
1170
- end
1171
-
1172
- def scope_allowed_attributes(attributes)
1173
- old_attributes = module_under_test::SafeListSanitizer.allowed_attributes
1174
- module_under_test::SafeListSanitizer.allowed_attributes = attributes
1175
- yield module_under_test::SafeListSanitizer.new
1176
- ensure
1177
- module_under_test::SafeListSanitizer.allowed_attributes = old_attributes
1178
- end
1179
-
1180
- def sanitize_css(input)
1181
- module_under_test::SafeListSanitizer.new.sanitize_css(input)
1182
- end
1183
-
1184
- # note that this is used for testing CSS hex encoding: \\[0-9a-f]{1,6}
1185
- def convert_to_css_hex(string, escape_parens = false)
1186
- string.chars.map do |c|
1187
- if !escape_parens && (c == "(" || c == ")")
1188
- c
1189
- else
1190
- format('\00%02X', c.ord)
1191
- end
1192
- end.join
1193
- end
1194
- end
1195
-
1196
- class HTML4SafeListSanitizerTest < Minitest::Test
1197
- @module_under_test = Rails::HTML4
1198
- include SafeListSanitizerTest
1199
- end
1200
-
1201
- class HTML5SafeListSanitizerTest < Minitest::Test
1202
- @module_under_test = Rails::HTML5
1203
- include SafeListSanitizerTest
1204
-
1205
- def test_should_not_be_vulnerable_to_nokogiri_foreign_style_serialization_bug
1206
- # https://hackerone.com/reports/2503220
1207
- input = "<svg><style>&lt;img src onerror=alert(1)>"
1208
- result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: ["svg", "style"])
1209
- browser = Nokogiri::HTML5::Document.parse(result)
1210
- xss = browser.at_xpath("//img/@onerror")
1211
-
1212
- assert_nil(xss)
1213
- end
1214
-
1215
- def test_should_not_be_vulnerable_to_ns_confusion_2519936
1216
- # https://hackerone.com/reports/2519936
1217
- input = "<math><style><style class='</style><script>alert(1)</script>'>"
1218
- result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: ["style"])
1219
- browser = Nokogiri::HTML5::Document.parse(result)
1220
- xss = browser.at_xpath("//script")
1221
-
1222
- assert_nil(xss)
1223
- end
1224
-
1225
- def test_should_not_be_vulnerable_to_ns_confusion_2519941
1226
- # https://hackerone.com/reports/2519941
1227
- input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
1228
- result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: %w(math style))
1229
- browser = Nokogiri::HTML5::Document.parse(result)
1230
- xss = browser.at_xpath("//img/@onerror")
1231
-
1232
- assert_nil(xss)
1233
- end
1234
-
1235
- def test_should_not_be_vulnerable_to_mglyph_namespace_confusion
1236
- # https://hackerone.com/reports/2519936
1237
- input = "<math><mtext><table><mglyph><style><img src=: onerror=alert(1)>"
1238
- tags = %w(math mtext table mglyph style)
1239
-
1240
- result = nil
1241
- assert_output(nil, /WARNING/) do
1242
- result = safe_list_sanitize(input, tags: tags)
1243
- end
1244
-
1245
- browser = Nokogiri::HTML5::Document.parse(result)
1246
- xss = browser.at_xpath("//img/@onerror")
1247
-
1248
- assert_nil(xss)
1249
- end
1250
-
1251
- def test_should_not_be_vulnerable_to_malignmark_namespace_confusion
1252
- # https://hackerone.com/reports/2519936
1253
- input = "<math><mtext><table><malignmark><style><img src=: onerror=alert(1)>"
1254
- tags = %w(math mtext table malignmark style)
1255
-
1256
- result = nil
1257
- assert_output(nil, /WARNING/) do
1258
- result = safe_list_sanitize(input, tags: tags)
1259
- end
1260
-
1261
- browser = Nokogiri::HTML5::Document.parse(result)
1262
- xss = browser.at_xpath("//img/@onerror")
1263
-
1264
- assert_nil(xss)
1265
- end
1266
-
1267
- def test_should_not_be_vulnerable_to_noscript_attacks
1268
- # https://hackerone.com/reports/2509647
1269
- skip("browser assertion requires parse_noscript_content_as_text") unless Nokogiri::VERSION >= "1.17"
1270
-
1271
- input = '<noscript><p id="</noscript><script>alert(1)</script>"></noscript>'
1272
-
1273
- result = nil
1274
- assert_output(nil, /WARNING/) do
1275
- result = Rails::HTML5::SafeListSanitizer.new.sanitize(input, tags: %w(p div noscript), attributes: %w(id class style))
1276
- end
1277
-
1278
- browser = Nokogiri::HTML5::Document.parse(result, parse_noscript_content_as_text: true)
1279
- xss = browser.at_xpath("//script")
1280
-
1281
- assert_nil(xss)
1282
- end
1283
- end if loofah_html5_support?
1284
- end