This file is indexed.

/usr/lib/ruby/vendor_ruby/qrack/transport/buffer09.rb is in ruby-bunny 0.7.8-1.

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
# encoding: utf-8

if [].map.respond_to? :with_index
  class Array #:nodoc:
    def enum_with_index
      each.with_index
    end
  end
else
  require 'enumerator'
end

module Qrack
  module Transport09 #:nodoc: all
    class Buffer

      def initialize data = ''
        @data = data
        @pos = 0
      end

      attr_reader :pos

      def data
        @data.clone
      end
      alias :contents :data
      alias :to_s :data

      def << data
        @data << data.to_s
        self
      end

      def length
        @data.bytesize
      end

      def empty?
        pos == length
      end

      def rewind
        @pos = 0
      end

      def read_properties *types
        types.shift if types.first == :properties

        i = 0
        values = []

        while props = read(:short)
          (0..14).each do |n|
            # no more property types
            break unless types[i]

            # if flag is set
            if props & (1<<(15-n)) != 0
              if types[i] == :bit
                # bit values exist in flags only
                values << true
              else
                # save type name for later reading
                values << types[i]
              end
            else
              # property not set or is false bit
              values << (types[i] == :bit ? false : nil)
            end

            i+=1
          end

          # bit(0) == 0 means no more property flags
          break unless props & 1 == 1
        end

        values.map do |value|
          value.is_a?(Symbol) ? read(value) : value
        end
      end

      def read *types
        if types.first == :properties
          return read_properties(*types)
        end

        values = types.map do |type|
          case type
          when :octet
            _read(1, 'C')
          when :short
            _read(2, 'n')
          when :long
            _read(4, 'N')
          when :longlong
            upper, lower = _read(8, 'NN')
            upper << 32 | lower
          when :shortstr
            _read read(:octet)
          when :longstr
            _read read(:long)
          when :timestamp
            Time.at read(:longlong)
          when :table
            t = Hash.new

            table = Buffer.new(read(:longstr))
            until table.empty?
              key, type = table.read(:shortstr, :octet)
              key = key.intern
              t[key] ||= case type
                         when 83 # 'S'
                           table.read(:longstr)
                         when 73 # 'I'
                           table.read(:long)
                         when 68 # 'D'
                           exp = table.read(:octet)
                           num = table.read(:long)
                           num / 10.0**exp
                         when 84 # 'T'
                           table.read(:timestamp)
                         when 70 # 'F'
                           table.read(:table)
                         when 116 # 't'
                           table.read(:octet)
                         end
            end

            t
          when :bit
            if (@bits ||= []).empty?
              val = read(:octet)
              @bits = (0..7).map{|i| (val & (1 << i)) != 0 }
            end

            @bits.shift
          else
            raise Qrack::InvalidTypeError, "Cannot read data of type #{type}"
          end
        end

        types.size == 1 ? values.first : values
      end

      def write type, data
        case type
        when :octet
          _write(data, 'C')
        when :short
          _write(data, 'n')
        when :long
          _write(data, 'N')
        when :longlong
          lower =  data & 0xffffffff
          upper = (data & ~0xffffffff) >> 32
          _write([upper, lower], 'NN')
        when :shortstr
          data = (data || '').to_s
          _write([data.bytesize, data], 'Ca*')
        when :longstr
          if data.is_a? Hash
            write(:table, data)
          else
            data = (data || '').to_s
            _write([data.bytesize, data], 'Na*')
          end
        when :timestamp
          write(:longlong, data.to_i)
        when :table
          data ||= {}
          write :longstr, (data.inject(Buffer.new) do |table, (key, value)|
                             table.write(:shortstr, key.to_s)

                             case value
                             when String
                               table.write(:octet, 83) # 'S'
                               table.write(:longstr, value.to_s)
                             when Fixnum
                               table.write(:octet, 73) # 'I'
                               table.write(:long, value)
                             when Float
                               table.write(:octet, 68) # 'D'
                               # XXX there's gotta be a better way to do this..
                               exp = value.to_s.split('.').last.bytesize
                               num = value * 10**exp
                               table.write(:octet, exp)
                               table.write(:long, num)
                             when Time
                               table.write(:octet, 84) # 'T'
                               table.write(:timestamp, value)
                             when Hash
                               table.write(:octet, 70) # 'F'
                               table.write(:table, value)
                             end

                             table
                           end)
        when :bit
          [*data].to_enum(:each_slice, 8).each{|bits|
            write(:octet, bits.enum_with_index.inject(0){ |byte, (bit, i)|
                    byte |= (1 << i) if bit
                    byte
                  })
          }
        when :properties
          values = []
          data.enum_with_index.inject(0) do |short, ((type, value), i)|
            n = i % 15
            last = i+1 == data.size

            if (n == 0 and i != 0) or last
              if data.size > i+1
                short |= (1 << 0)
              elsif last and value
                values << [type,value]
                short |= 1<<(15-n)
              end

              write(:short, short)
              short = 0
            end

            if value and !last
              values << [type,value]
              short |= 1<<(15-n)
            end

            short
          end

          values.each do |type, value|
            write(type, value) unless type == :bit
          end
        else
          raise Qrack::InvalidTypeError, "Cannot write data of type #{type}"
        end

        self
      end

      def extract
        begin
          cur_data, cur_pos = @data.clone, @pos
          yield self
        rescue Qrack::BufferOverflowError
          @data, @pos = cur_data, cur_pos
          nil
        end
      end

      def _read(size, pack = nil)
        if @data.is_a?(Qrack::Client)
          raw = @data.read(size)
          return raw if raw.nil? or pack.nil?
          return raw.unpack(pack).first
        end

        if @pos + size > length
          raise Qrack::BufferOverflowError
        else
          data = @data[@pos,size]
          @data[@pos,size] = ''
          if pack
            data = data.unpack(pack)
            data = data.pop if data.size == 1
          end
          data
        end
      end

      def _write data, pack = nil
        data = [*data].pack(pack) if pack
        @data[@pos,0] = data
        @pos += data.bytesize
      end
    end
  end
end