Module: FiberAudit::Runtime::Probes::Socket

Defined in:
lib/fiber_audit/runtime/probes/socket.rb

Defined Under Namespace

Modules: ConstructorHook

Constant Summary collapse

MODULE_NAME =
Module.instance_method(:name)
MODULE_COMPARE =
Module.instance_method(:<=)
CONST_DEFINED =
Module.instance_method(:const_defined?)
CONST_GET =
Module.instance_method(:const_get)

Class Method Summary collapse

Class Method Details

.exact_socket?(klass, name) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
45
46
# File 'lib/fiber_audit/runtime/probes/socket.rb', line 42

def exact_socket?(klass, name)
  return false unless OperationVocabulary::FA1006_EXACT.include?(name)

  resolve_constant(name).equal?(klass)
end

.install!(registry) ⇒ Object



25
26
27
28
29
# File 'lib/fiber_audit/runtime/probes/socket.rb', line 25

def install!(registry)
  return unless defined?(::BasicSocket)

  registry.prepend_once(::BasicSocket.singleton_class, ConstructorHook)
end

.ip_socket_subclass?(klass) ⇒ Boolean

Returns:

  • (Boolean)


48
49
50
51
52
# File 'lib/fiber_audit/runtime/probes/socket.rb', line 48

def ip_socket_subclass?(klass)
  return false unless defined?(::IPSocket)

  MODULE_COMPARE.bind_call(klass, ::IPSocket) == true
end

.operation_for(klass) ⇒ Object



31
32
33
34
35
36
37
38
39
40
# File 'lib/fiber_audit/runtime/probes/socket.rb', line 31

def operation_for(klass)
  name = MODULE_NAME.bind_call(klass)
  return unless safe_constant_name?(name)
  return unless exact_socket?(klass, name) || ip_socket_subclass?(klass)
  return unless resolve_constant(name).equal?(klass)

  "#{name}.new"
rescue StandardError
  nil
end

.resolve_constant(name) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/fiber_audit/runtime/probes/socket.rb', line 59

def resolve_constant(name)
  namespace = Object
  name.split('::').each do |part|
    unless CONST_DEFINED.bind_call(namespace, part, false)
      namespace = nil
      break
    end

    namespace = CONST_GET.bind_call(namespace, part, false)
  end
  namespace
rescue NameError, TypeError
  nil
end

.safe_constant_name?(name) ⇒ Boolean

Returns:

  • (Boolean)


54
55
56
57
# File 'lib/fiber_audit/runtime/probes/socket.rb', line 54

def safe_constant_name?(name)
  name.is_a?(String) && name.bytesize <= 240 &&
    name.match?(/\A[A-Z][A-Za-z0-9_]*(?:::[A-Z][A-Za-z0-9_]*)*\z/)
end