This file is indexed.

/usr/lib/ruby/vendor_ruby/merb-core/controller/template.rb is in ruby-merb-core 1.1.3+dfsg-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
module Merb::InlineTemplates
end

module Merb::Template
  
  EXTENSIONS            = {} unless defined?(EXTENSIONS)
  METHOD_LIST           = {} unless defined?(METHOD_LIST)
  SUPPORTED_LOCALS_LIST = Hash.new([].freeze) unless defined?(SUPPORTED_LOCALS_LIST)
  MTIMES                = {} unless defined?(MTIMES)
  
  class << self
    # Get the template's method name from a full path. This replaces
    # non-alphanumeric characters with __ and "." with "_"
    #
    # Collisions are potentially possible with something like:
    # ~foo.bar and __foo.bar or !foo.bar.
    #
    # ==== Parameters
    # path<String>:: A full path to convert to a valid Ruby method name
    #
    # ==== Returns
    # String:: The template name.
    #
    #
    # We might want to replace this with something that varies the
    # character replaced based on the non-alphanumeric character
    # to avoid edge-case collisions.
    #
    # :api: private
    def template_name(path)
      path = File.expand_path(path)      
      path.gsub(/[^\.a-zA-Z0-9]/, "__").gsub(/\./, "_")
    end

    chainable do
      # For a given path, get an IO object that responds to #path.
      #
      # This is so that plugins can override this if they provide
      # mechanisms for specifying templates that are not just simple
      # files. The plugin is responsible for ensuring that the fake
      # path provided will work with #template_for, and thus the
      # RenderMixin in general.
      #
      # ==== Parameters
      # path<String>:: A full path to find a template for. This is the
      #   path that the RenderMixin assumes it should find the template
      #   in.
      # 
      # ==== Returns
      # IO#path:: An IO object that responds to path (File or VirtualFile).
      #
      # :api: plugin
      # @overridable
      def load_template_io(path)
        file = Dir["#{path}.{#{template_extensions.join(',')}}"].first
        File.open(file, "r") if file
      end
    end

    # Get the name of the template method for a particular path.
    #
    # ==== Parameters
    # path<String>:: A full path to find a template method for.
    # template_stack<Array>:: The template stack. Not used.
    # locals<Array[Symbol]>:: The names of local variables
    #
    # ==== Returns
    # <String>:: name of the method that inlines the template.
    #
    # :api: private
    def template_for(path, template_stack = [], locals=[])
      path = File.expand_path(path)
      
      if needs_compilation?(path, locals)
        template_io = load_template_io(path)
        METHOD_LIST[path] = inline_template(template_io, locals) if template_io
      end
      
      METHOD_LIST[path]
    end
    
    # Decide if a template needs to be re/compiled.
    #
    # ==== Parameters
    # path<String>:: The full path of the template to check support for.
    # locals<Array[Symbol]>:: The list of locals that need to be supported
    #
    # ==== Returns
    # Boolean:: Whether or not the template for the provided path needs to be recompiled
    #
    # :api: private
    def needs_compilation?(path, locals)
      return true if Merb::Config[:reload_templates] || !METHOD_LIST[path]
      
      current_locals = SUPPORTED_LOCALS_LIST[path]
      current_locals != locals &&
        !(locals - current_locals).empty?
    end
    
    # Get all known template extensions
    #
    # ==== Returns
    #   Array:: Extension strings.
    #
    # :api: plugin
    def template_extensions
      EXTENSIONS.keys
    end
    
    # Takes a template at a particular path and inlines it into a module and
    # adds it to the METHOD_LIST table to speed lookup later.
    # 
    # ==== Parameters
    # io<#path>::
    #   An IO that responds to #path (File or VirtualFile)
    # locals<Array[Symbol]>::
    #   A list of local names that should be assigned in the template method
    #   from the arguments hash. Defaults to [].
    # mod<Module>::
    #   The module to put the compiled method into. Defaults to
    #   Merb::InlineTemplates
    #
    # ==== Returns
    # Symbol:: The name of the method that the template was compiled into.
    #
    # ==== Notes
    # Even though this method supports inlining into any module, the method
    # must be available to instances of AbstractController that will use it.
    #
    # :api: private
    def inline_template(io, locals=[], mod = Merb::InlineTemplates)
      full_file_path = File.expand_path(io.path)
      engine_neutral_path = full_file_path.gsub(/\.[^\.]*$/, "")
      
      local_list = (SUPPORTED_LOCALS_LIST[engine_neutral_path] |= locals)
      ret = METHOD_LIST[engine_neutral_path] =
        engine_for(full_file_path).compile_template(io, 
        template_name(full_file_path), local_list, mod)
        
      io.close
      ret
    end
    
    # Finds the engine for a particular path.
    # 
    # ==== Parameters
    # path<String>:: The path of the file to find an engine for.
    #
    # ==== Returns
    # Class:: The engine.
    #
    # :api: private
    def engine_for(path)
      path = File.expand_path(path)      
      EXTENSIONS[path.match(/\.([^\.]*)$/)[1]]
    end
    
    # Registers the extensions that will trigger a particular templating
    # engine.
    # 
    # ==== Parameters
    # engine<Class>:: The class of the engine that is being registered
    # extensions<Array[String]>:: 
    #   The list of extensions that will be registered with this templating
    #   language
    #
    # ==== Raises
    # ArgumentError:: engine does not have a compile_template method.
    #
    # ==== Returns
    # nil
    #
    # ==== Example
    #   Merb::Template.register_extensions(Merb::Template::Erubis, ["erb"])
    #
    # :api: plugin
    def register_extensions(engine, extensions) 
      raise ArgumentError, "The class you are registering does not have a compile_template method" unless
        engine.respond_to?(:compile_template)
      extensions.each{|ext| EXTENSIONS[ext] = engine }
      Merb::AbstractController.class_eval <<-HERE
        include #{engine}::Mixin
      HERE
    end
  end
  
  require 'erubis'

  class Erubis    
    # Fixing bug in Erubis
    # http://rubyforge.org/tracker/index.php?func=detail&aid=21825&group_id=1320&atid=5201
    XmlHelper = ::Erubis::XmlHelper

    # ==== Parameters
    # io<#path>:: An IO containing the full path of the template.
    # name<String>:: The name of the method that will be created.
    # locals<Array[Symbol]>:: A list of locals to assign from the args passed into the compiled template.
    # mod<Module>:: The module that the compiled method will be placed into.
    #
    # :api: private
    def self.compile_template(io, name, locals, mod)
      template = ::Erubis::BlockAwareEruby.new(io.read)
      _old_verbose, $VERBOSE = $VERBOSE, nil
      assigns = locals.inject([]) do |assigns, local|
        assigns << "#{local} = _locals[#{local.inspect}]"
      end.join(";")
      
      code = "def #{name}(_locals={}); #{assigns}; #{template.src}; end"
      mod.module_eval code, File.expand_path(io.path)
      $VERBOSE = _old_verbose
      
      name
    end

    module Mixin
      
      # ==== Parameters
      # *args:: Arguments to pass to the block.
      # &block:: The template block to call.
      #
      # ==== Returns
      # String:: The output of the block.
      #
      # ==== Examples
      # Capture being used in a .html.erb page:
      # 
      #   <% @foo = capture do %>
      #     <p>Some Foo content!</p> 
      #   <% end %>
      #
      # :api: private
      def capture_erb(*args, &block)
        _old_buf, @_erb_buf = @_erb_buf, ""
        block.call(*args)
        ret = @_erb_buf
        @_erb_buf = _old_buf
        ret
      end

      # :api: private
      def concat_erb(string, binding)
        @_erb_buf << string
      end
            
    end
  
    Merb::Template.register_extensions(self, %w[erb])    
  end
  
end

module Erubis
  module BlockAwareEnhancer
    # :api: private
    def add_preamble(src)
      src << "_old_buf, @_erb_buf = @_erb_buf, ''; "
      src << "@_engine = 'erb'; "
    end

    # :api: private
    def add_postamble(src)
      src << "\n" unless src[-1] == ?\n      
      src << "_ret = @_erb_buf; @_erb_buf = _old_buf; _ret.to_s;\n"
    end

    # :api: private
    def add_text(src, text)
      src << " @_erb_buf.concat('" << escape_text(text) << "'); "
    end

    # :api: private
    def add_expr_escaped(src, code)
      src << ' @_erb_buf.concat(' << escaped_expr(code) << ');'
    end
    
    # :api: private
    def add_stmt2(src, code, tailch)
      src << code
      src << ") ).to_s; " if tailch == "="
      src << ';' unless code[-1] == ?\n
    end
    
    # :api: private
    def add_expr_literal(src, code)
      if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/
        src << ' @_erb_buf.concat( (' << code << "; "
      else
        src << ' @_erb_buf.concat((' << code << ').to_s);'
      end
    end
  end

  class BlockAwareEruby < Eruby
    include BlockAwareEnhancer
  end
  
  # module RubyEvaluator
  # 
  #   # DOC
  #   def def_method(object, method_name, filename=nil)
  #     m = object.is_a?(Module) ? :module_eval : :instance_eval
  #     setup = "@_engine = 'erb'"
  #     object.__send__(m, "def #{method_name}(locals={}); #{setup}; #{@src}; end", filename || @filename || '(erubis)')
  #   end
  #  
  # end
end