From f9b36820ef862e3438f30365a3f3d4ab4079f34b Mon Sep 17 00:00:00 2001 From: Kyle Zhao Date: Thu, 1 Nov 2018 16:01:46 -0400 Subject: [PATCH] FIX: only extract script tags with certain types (#6553) `script` tags with custom types (e.g. `text/template`) are not executed by the browser, and should not be extracted into an external theme JavaScript --- app/models/theme_field.rb | 23 +++++++++++++++++++++-- spec/models/theme_field_spec.rb | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/app/models/theme_field.rb b/app/models/theme_field.rb index 84a6b9b561e..01b5c4c9fc2 100644 --- a/app/models/theme_field.rb +++ b/app/models/theme_field.rb @@ -123,9 +123,10 @@ COMPILED end doc.css('script').each do |node| - next if node['src'].present? + next unless inline_javascript?(node) - javascript_cache.content << "(function() { #{node.inner_html} })();" + javascript_cache.content << node.inner_html + javascript_cache.content << "\n" node.remove end @@ -253,6 +254,24 @@ COMPILED MessageBus.publish "/header-change/#{theme.id}", self.value if theme && self.name == "header" MessageBus.publish "/footer-change/#{theme.id}", self.value if theme && self.name == "footer" end + + private + + JAVASCRIPT_TYPES = %w( + text/javascript + application/javascript + application/ecmascript + ) + + def inline_javascript?(node) + if node['src'].present? + false + elsif node['type'].present? + JAVASCRIPT_TYPES.include?(node['type'].downcase) + else + true + end + end end # == Schema Information diff --git a/spec/models/theme_field_spec.rb b/spec/models/theme_field_spec.rb index b129c3143cf..5052c883b60 100644 --- a/spec/models/theme_field_spec.rb +++ b/spec/models/theme_field_spec.rb @@ -37,9 +37,18 @@ describe ThemeField do + + + HTML @@ -47,8 +56,27 @@ describe ThemeField do expect(theme_field.value_baked).to include("") expect(theme_field.value_baked).to include("external-script.js") - expect(theme_field.javascript_cache.content).to include('inline discourse plugin') - expect(theme_field.javascript_cache.content).to include('inline raw script') + expect(theme_field.value_baked).to include(' + + HTML + + extracted = <<~JavaScript + var a = 10 + var b = 10 + JavaScript + + theme_field = ThemeField.create!(theme_id: 1, target_id: 0, name: "header", value: html) + + expect(theme_field.javascript_cache.content).to eq(extracted) end it "correctly extracts and generates errors for transpiled js" do