This file is indexed.

/usr/lib/ruby/vendor_ruby/gir_ffi/info_ext/i_type_info.rb is in ruby-gir-ffi 0.9.0-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
require 'gir_ffi/builder_helper'

module GirFFI
  module InfoExt
    # Extensions for GObjectIntrospection::ITypeInfo needed by GirFFI
    module ITypeInfo
      def self.flattened_tag_to_gtype_map
        @flattened_tag_to_gtype_map ||= {
          array:    GObject::TYPE_ARRAY,
          c:        GObject::TYPE_POINTER,
          gboolean: GObject::TYPE_BOOLEAN,
          ghash:    GObject::TYPE_HASH_TABLE,
          gint32:   GObject::TYPE_INT,
          gint64:   GObject::TYPE_INT64,
          guint64:  GObject::TYPE_UINT64,
          strv:     GObject::TYPE_STRV,
          utf8:     GObject::TYPE_STRING,
          void:     GObject::TYPE_NONE
        }
      end

      def gtype
        if tag == :interface
          return interface.gtype
        elsif (type = ITypeInfo.flattened_tag_to_gtype_map[flattened_tag])
          return type
        else
          raise "Can't find GType for #{flattened_tag} pointer? = #{pointer?}"
        end
      end

      def make_g_value
        GObject::Value.for_gtype gtype
      end

      def element_type
        case tag
        when :glist, :gslist, :array, :c
          enumerable_element_type
        when :ghash
          dictionary_element_type
        end
      end

      def flattened_tag
        case tag
        when :interface
          interface_type
        when :array
          flattened_array_type
        else
          tag
        end
      end

      def interface_type
        tag == :interface && interface.info_type
      end

      def tag_or_class
        base = case tag
               when:interface
                 Builder.build_class interface
               when :ghash
                 [tag, *element_type]
               else
                 flattened_tag
               end
        if pointer? && tag != :utf8 && tag != :filename
          [:pointer, base]
        else
          base
        end
      end

      TAG_TO_WRAPPER_CLASS_MAP = {
        array:           'GLib::Array',
        byte_array:      'GLib::ByteArray',
        c:               'GirFFI::SizedArray',
        error:           'GLib::Error',
        ghash:           'GLib::HashTable',
        glist:           'GLib::List',
        gslist:          'GLib::SList',
        ptr_array:       'GLib::PtrArray',
        strv:            'GLib::Strv',
        utf8:            'GirFFI::InPointer',
        void:            'GirFFI::InPointer',
        zero_terminated: 'GirFFI::ZeroTerminated'
      }

      # TODO: Use class rather than class name
      def argument_class_name
        if tag == :interface
          interface.full_type_name
        else
          TAG_TO_WRAPPER_CLASS_MAP[flattened_tag]
        end
      end

      def to_ffi_type
        return :pointer if pointer?

        case tag
        when :interface
          interface.to_ffi_type
        when :array
          [subtype_ffi_type(0), array_fixed_size]
        else
          TypeMap.map_basic_type tag
        end
      end

      def to_callback_ffi_type
        return :pointer if pointer?

        case tag
        when :interface
          # TODO: Move this logic into interface
          case interface.info_type
          when :enum, :flags
            :int32
          else
            :pointer
          end
        when :gboolean
          # TODO: Move this logic into TypeMap
          :bool
        else
          TypeMap.map_basic_type tag
        end
      end

      TAGS_NEEDING_RUBY_TO_C_CONVERSION = [
        :array, :c, :callback, :error, :ghash, :glist, :gslist, :object,
        :ptr_array, :struct, :strv, :utf8, :void, :zero_terminated
      ]

      TAGS_NEEDING_C_TO_RUBY_CONVERSION = [
        :array, :byte_array, :c, :error, :filename, :ghash, :glist, :gslist,
        :interface, :object, :ptr_array, :struct, :strv, :union, :utf8,
        :zero_terminated
      ]

      def needs_ruby_to_c_conversion_for_functions?
        TAGS_NEEDING_RUBY_TO_C_CONVERSION.include?(flattened_tag)
      end

      def needs_c_to_ruby_conversion_for_functions?
        TAGS_NEEDING_C_TO_RUBY_CONVERSION.include?(flattened_tag)
      end

      def needs_ruby_to_c_conversion_for_callbacks?
        [:enum].include?(flattened_tag) ||
          needs_ruby_to_c_conversion_for_functions?
      end

      def needs_c_to_ruby_conversion_for_callbacks?
        [:callback, :enum].include?(flattened_tag) ||
          needs_c_to_ruby_conversion_for_functions?
      end

      def needs_c_to_ruby_conversion_for_closures?
        [:array, :c, :ghash, :struct, :strv].include?(flattened_tag)
      end

      def needs_ruby_to_c_conversion_for_closures?
        [:array].include?(flattened_tag)
      end

      def extra_conversion_arguments
        case flattened_tag
        when :utf8, :void
          [flattened_tag]
        when :c
          [element_type, array_fixed_size]
        when :array, :ghash, :glist, :gslist, :ptr_array, :zero_terminated
          [element_type]
        else
          []
        end
      end

      GOBJECT_VALUE_NAME = 'GObject::Value'

      def gvalue?
        argument_class_name == GOBJECT_VALUE_NAME
      end

      private

      def subtype_tag_or_class(index)
        param_type(index).tag_or_class
      end

      def dictionary_element_type
        [subtype_tag_or_class(0), subtype_tag_or_class(1)]
      end

      def enumerable_element_type
        subtype_tag_or_class 0
      end

      def subtype_ffi_type(index)
        subtype = param_type(index).to_ffi_type
        if subtype == :pointer
          # NOTE: Don't use pointer directly to appease JRuby.
          :"uint#{FFI.type_size(:pointer) * 8}"
        else
          subtype
        end
      end

      def flattened_array_type
        if zero_terminated?
          zero_terminated_array_type
        else
          array_type
        end
      end

      def zero_terminated_array_type
        case element_type
        when :utf8, :filename
          :strv
        else
          :zero_terminated
        end
      end
    end
  end
end

GObjectIntrospection::ITypeInfo.send :include, GirFFI::InfoExt::ITypeInfo