This file is indexed.

/usr/lib/ruby/vendor_ruby/global_id/uri/gid.rb is in ruby-globalid 0.3.6-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
require 'uri/generic'
require 'active_support/core_ext/module/aliasing'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/hash/indifferent_access'

module URI
  class GID < Generic
    # URI::GID encodes an app unique reference to a specific model as an URI.
    # It has the components: app name, model class name, model id and params.
    # All components except params are required.
    #
    # The URI format looks like "gid://app/model_name/model_id".
    #
    # Simple metadata can be stored in params. Useful if your app has multiple databases,
    # for instance, and you need to find out which one to look up the model in.
    #
    # Params will be encoded as query parameters like so
    # "gid://app/model_name/model_id?key=value&another_key=another_value".
    #
    # Params won't be typecast, they're always strings.
    # For convenience params can be accessed using both strings and symbol keys.
    #
    # Multi value params aren't supported. Any params encoding multiple values under
    # the same key will return only the last value. For example, when decoding
    # params like "key=first_value&key=last_value" key will only be last_value.
    #
    # Read the documentation for +parse+, +create+ and +build+ for more.
    alias :app :host
    attr_reader :model_name, :model_id, :params

    # Raised when creating a Global ID for a model without an id
    class MissingModelIdError < URI::InvalidComponentError; end

    class << self
      # Validates +app+'s as URI hostnames containing only alphanumeric characters
      # and hyphens. An ArgumentError is raised if +app+ is invalid.
      #
      #   URI::GID.validate_app('bcx')     # => 'bcx'
      #   URI::GID.validate_app('foo-bar') # => 'foo-bar'
      #
      #   URI::GID.validate_app(nil)       # => ArgumentError
      #   URI::GID.validate_app('foo/bar') # => ArgumentError
      def validate_app(app)
        parse("gid://#{app}/Model/1").app
      rescue URI::Error
        raise ArgumentError, 'Invalid app name. ' \
          'App names must be valid URI hostnames: alphanumeric and hyphen characters only.'
      end

      # Create a new URI::GID by parsing a gid string with argument check.
      #
      #   URI::GID.parse 'gid://bcx/Person/1?key=value'
      #
      # This differs from URI() and URI.parse which do not check arguments.
      #
      #   URI('gid://bcx')             # => URI::GID instance
      #   URI.parse('gid://bcx')       # => URI::GID instance
      #   URI::GID.parse('gid://bcx/') # => raises URI::InvalidComponentError
      def parse(uri)
        generic_components = URI.split(uri) << nil << true # nil parser, true arg_check
        new(*generic_components)
      end

      # Shorthand to build a URI::GID from an app, a model and optional params.
      #
      #   URI::GID.create('bcx', Person.find(5), database: 'superhumans')
      def create(app, model, params = nil)
        build app: app, model_name: model.class.name, model_id: model.id, params: params
      end

      # Create a new URI::GID from components with argument check.
      #
      # The allowed components are app, model_name, model_id and params, which can be
      # either a hash or an array.
      #
      # Using a hash:
      #
      #   URI::GID.build(app: 'bcx', model_name: 'Person', model_id: '1', params: { key: 'value' })
      #
      # Using an array, the arguments must be in order [app, model_name, model_id, params]:
      #
      #   URI::GID.build(['bcx', 'Person', '1', key: 'value'])
      def build(args)
        parts = Util.make_components_hash(self, args)
        parts[:host] = parts[:app]
        parts[:path] = "/#{parts[:model_name]}/#{CGI.escape(parts[:model_id].to_s)}"

        if parts[:params] && !parts[:params].empty?
          parts[:query] = URI.encode_www_form(parts[:params])
        end

        super parts
      end
    end

    def to_s
      # Implement #to_s to avoid no implicit conversion of nil into string when path is nil
      "gid://#{app}#{path}#{'?' + query if query}"
    end

    protected
      def set_path(path)
        set_model_components(path) unless defined?(@model_name) && @model_id
        super
      end

      # Ruby 2.2 uses #query= instead of #set_query
      def query=(query)
        set_params parse_query_params(query)
        super
      end

      # Ruby 2.1 or less uses #set_query to assign the query
      def set_query(query)
        set_params parse_query_params(query)
        super
      end

      def set_params(params)
        @params = params
      end

    private
      COMPONENT = [ :scheme, :app, :model_name, :model_id, :params ].freeze

      # Extracts model_name and model_id from the URI path.
      PATH_REGEXP = %r(\A/([^/]+)/?([^/]+)?\z)

      def check_host(host)
        validate_component(host)
        super
      end

      def check_path(path)
        validate_component(path)
        set_model_components(path, true)
      end

      def check_scheme(scheme)
        if scheme == 'gid'
          super
        else
          raise URI::BadURIError, "Not a gid:// URI scheme: #{inspect}"
        end
      end

      def set_model_components(path, validate = false)
        _, model_name, model_id = path.match(PATH_REGEXP).to_a
        model_id = CGI.unescape(model_id) if model_id

        validate_component(model_name) && validate_model_id(model_id, model_name) if validate

        @model_name = model_name
        @model_id = model_id
      end

      def validate_component(component)
        return component unless component.blank?

        raise URI::InvalidComponentError,
          "Expected a URI like gid://app/Person/1234: #{inspect}"
      end

      def validate_model_id(model_id, model_name)
        return model_id unless model_id.blank?

        raise MissingModelIdError, "Unable to create a Global ID for " \
          "#{model_name} without a model id."
      end

      def parse_query_params(query)
        Hash[URI.decode_www_form(query)].with_indifferent_access if query
      end
  end

  @@schemes['GID'] = GID
end