Module: Ibex::Runtime::EventSanitizer

Defined in:
lib/ibex/runtime/event_sanitizer.rb,
sig/ibex/runtime/event_sanitizer.rbs

Overview

Converts application-owned values into bounded, data-only event summaries. rubocop:disable Metrics/ModuleLength

Constant Summary collapse

MAX_DEPTH =

Signature:

  • Integer

Returns:

  • (Integer)
3
MAX_COLLECTION_ENTRIES =

Signature:

  • Integer

Returns:

  • (Integer)
16
MAX_STRING_BYTES =

Signature:

  • Integer

Returns:

  • (Integer)
256
MAX_INTEGER_BITS =

Signature:

  • Integer

Returns:

  • (Integer)
64
STRING_INPUT_BYTES =

Signature:

  • Integer

Returns:

  • (Integer)
1_024
DATA_MAX_DEPTH =

Signature:

  • Integer

Returns:

  • (Integer)
16

Class Method Summary collapse

Class Method Details

.class_name(input) ⇒ String

RBS:

  • (untyped input) -> String

Parameters:

  • input (Object)

Returns:

  • (String)


82
83
84
85
86
87
88
# File 'lib/ibex/runtime/event_sanitizer.rb', line 82

def class_name(input)
  klass = core_call(Object, :class, input)
  name = core_call(Module, :name, klass)
  core_type?(name, String) && !core_call(String, :empty?, name) ? string(name) : "<anonymous>"
rescue StandardError
  "<unknown>"
end

.data(input) ⇒ Hash[String, untyped]

Copy a runtime payload into deeply frozen JSON data. Unknown objects are summarized instead of being retained, so callers cannot smuggle mutable application identities into an Event.

RBS:

  • (Hash[untyped, untyped] input) -> Hash[String, untyped]

Parameters:

  • input (Hash[untyped, untyped])

Returns:

  • (Hash[String, untyped])


21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/ibex/runtime/event_sanitizer.rb', line 21

def data(input)
  result = {} #: Hash[String, untyped]
  consumed = 0
  core_call(Hash, :each_pair, input) do |key, raw|
    break if consumed == MAX_COLLECTION_ENTRIES

    consumed += 1
    result[data_key(key)] = json_data(raw, depth: 0, seen: {})
  end
  result.freeze
rescue StandardError
  { "unavailable" => "event_data" }.freeze
end

.location(location) ⇒ Hash[String, untyped]?

RBS:

  • (untyped location) -> Hash[String, untyped]?

Parameters:

  • location (Object)

Returns:

  • (Hash[String, untyped], nil)


43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/ibex/runtime/event_sanitizer.rb', line 43

def location(location)
  return nil unless location

  fields = {
    "file" => location_field(location, :file),
    "line" => location_field(location, :line),
    "column" => location_field(location, :column),
    "end_line" => location_field(location, :end_line),
    "end_column" => location_field(location, :end_column)
  }
  fields.compact.transform_values { |entry| value(entry) }.freeze
rescue StandardError
  unavailable("location")
end

.string(input) ⇒ String

RBS:

  • (untyped input) -> String

Parameters:

  • input (Object)

Returns:

  • (String)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/ibex/runtime/event_sanitizer.rb', line 59

def string(input)
  return "<unavailable>" unless core_type?(input, String)

  prefix = core_call(String, :byteslice, input, 0, STRING_INPUT_BYTES) || ""
  encoded = core_call(
    String,
    :encode,
    prefix,
    Encoding::UTF_8,
    invalid: :replace,
    undef: :replace,
    replace: "\uFFFD"
  )
  encoded_bytes = core_call(String, :bytesize, encoded)
  input_bytes = core_call(String, :bytesize, input)
  return encoded.freeze if encoded_bytes <= MAX_STRING_BYTES && input_bytes <= STRING_INPUT_BYTES

  truncate_utf8(encoded)
rescue StandardError
  "<unavailable>"
end

.value(input) ⇒ Object

RBS:

  • (untyped input) -> untyped

Parameters:

  • input (Object)

Returns:

  • (Object)


36
37
38
39
40
# File 'lib/ibex/runtime/event_sanitizer.rb', line 36

def value(input)
  summarize(input, depth: 0, seen: {})
rescue StandardError
  unavailable("sanitization")
end