Class: Msf::OptArray

Inherits:
OptBase show all
Defined in:
lib/msf/core/opt_array.rb

Overview

Array option - allows multiple discrete values separated by a delimiter.

Constant Summary collapse

DEFAULT_SEPARATOR =

Default separator - matches comma separated values

','

Instance Attribute Summary collapse

Attributes inherited from OptBase

#advanced, #aliases, #conditions, #default, #enums, #evasion, #fallbacks, #max_length, #name, #owner, #regex, #required

Instance Method Summary collapse

Methods inherited from OptBase

#advanced?, #empty_required_value?, #evasion?, #invalid_value_length?, #required?, #type?, #validate_on_assignment?

Constructor Details

#initialize(in_name, attrs = [], accepted: nil, separator: nil, strip_whitespace: true, unique: true, **kwargs) ⇒ OptArray

Returns a new instance of OptArray.

Parameters:

  • in_name (String)

    the option name

  • attrs (Array) (defaults to: [])

    standard option attributes [required, description, default]

  • accepted (Array<String>) (defaults to: nil)

    optional list of accepted values (like OptEnum)

  • separator (String, Regexp) (defaults to: nil)

    the character or regex by which members should be split

  • strip_whitespace (Boolean) (defaults to: true)

    whether leading/trailing whitespace should be removed from each member

  • unique (Boolean) (defaults to: true)

    whether duplicate members should be removed

  • kwargs

    additional keyword arguments passed to OptBase



24
25
26
27
28
29
30
31
32
# File 'lib/msf/core/opt_array.rb', line 24

def initialize(in_name, attrs = [],
               accepted: nil, separator: nil, strip_whitespace: true, unique: true, **kwargs)
  super(in_name, attrs, **kwargs)
  
  @accepted = accepted ? [*accepted].map(&:to_s) : nil
  @separator = separator || DEFAULT_SEPARATOR
  @strip_whitespace = strip_whitespace
  @unique = unique
end

Instance Attribute Details

#acceptedObject (readonly)

Accessor for accepted values



112
113
114
# File 'lib/msf/core/opt_array.rb', line 112

def accepted
  @accepted
end

#desc_stringObject (protected)

:nodoc:



144
145
146
# File 'lib/msf/core/opt_array.rb', line 144

def desc_string
  @desc_string
end

Instance Method Details

#case_sensitive?Boolean (protected)

Determines if accepted values are case-sensitive Uses the same logic as OptEnum - if all accepted values are unique when downcased, then we’re case-insensitive

Returns:

  • (Boolean)

    true if case-sensitive, false otherwise



139
140
141
142
# File 'lib/msf/core/opt_array.rb', line 139

def case_sensitive?
  return true unless @accepted
  @accepted.map(&:downcase).uniq.length != @accepted.uniq.length
end

#descObject



101
102
103
104
105
106
107
108
109
# File 'lib/msf/core/opt_array.rb', line 101

def desc
  str = @desc_string || ''
  if @accepted
    accepted_str = @accepted.join(', ')
    "#{str} (Accepted: #{accepted_str})"
  else
    str
  end
end

#desc=(value) ⇒ Object

Override desc to include accepted values if defined



96
97
98
99
# File 'lib/msf/core/opt_array.rb', line 96

def desc=(value)
  @desc_string = value
  desc
end

#display_value(value) ⇒ String

Returns a user-friendly display of the value

Parameters:

  • value (String, Array)

    the value to display

Returns:

  • (String)

    comma-separated string representation



88
89
90
91
92
93
# File 'lib/msf/core/opt_array.rb', line 88

def display_value(value)
  arr = value.is_a?(Array) ? value : value_to_array(value)
  arr.join(', ')
rescue
  value.to_s
end

#normalize(value = self.value) ⇒ Array?

Normalizes the value to an array with proper formatting

Parameters:

  • value (String, Array) (defaults to: self.value)

    the value to normalize

Returns:

  • (Array, nil)

    normalized array or nil if invalid



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/msf/core/opt_array.rb', line 64

def normalize(value = self.value)
  return nil if value.nil?
  
  arr = value_to_array(value)
  
  # Apply uniqueness if requested
  arr = arr.uniq if @unique
  
  # Normalize case if accepted values are defined and case-insensitive
  if @accepted && !case_sensitive?
    arr = arr.map do |member|
      @accepted.find { |a| a.casecmp?(member) } || member
    end
  end
  
  # Return nil if validation fails
  return nil unless valid?(arr, check_empty: false)
  
  arr
end

#typeObject



13
14
15
# File 'lib/msf/core/opt_array.rb', line 13

def type
  'array'
end

#valid?(value = self.value, check_empty: true, datastore: nil) ⇒ Boolean

Validates the array option value

Parameters:

  • value (String, Array) (defaults to: self.value)

    the value to validate

  • check_empty (Boolean) (defaults to: true)

    whether to check for empty required values

  • datastore (Hash) (defaults to: nil)

    the datastore (unused but part of interface)

Returns:

  • (Boolean)

    true if valid, false otherwise



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/msf/core/opt_array.rb', line 39

def valid?(value = self.value, check_empty: true, datastore: nil)
  return false if check_empty && required? && value.to_s.empty?
  return true if value.nil? && !required?
  return false if value.nil?

  # Normalize to array
  arr = value_to_array(value)
  
  # If accepted values are defined, validate each member
  if @accepted
    arr.all? do |member|
      if case_sensitive?
        @accepted.include?(member)
      else
        @accepted.map(&:downcase).include?(member.downcase)
      end
    end
  else
    true
  end
end

#value_to_array(value) ⇒ Array (protected)

Converts a value to an array

Parameters:

  • value (String, Array)

    the value to convert

Returns:

  • (Array)

    the resulting array



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/msf/core/opt_array.rb', line 119

def value_to_array(value)
  return value if value.is_a?(Array)
  return [] if value.nil? || value.to_s.empty?

  # Split by separator
  arr = value.to_s.split(@separator)

  # Strip whitespace and remove empty strings from each member if requested
  if @strip_whitespace
    arr = arr.map(&:strip)
    arr.reject!(&:empty?)
  end

  arr
end