rex-text 0.2.48 → 0.2.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e3ab248f34fa3b7917bad07015868aebb7e91af8af1a210fa90cb89da7b8edc
4
- data.tar.gz: 853d7652f999e24504754ad1416faed2a68377c0c29e4d74ff1189b2c7194f01
3
+ metadata.gz: 26e1e4f195a13ca2269745675f94c71bd02c1de0b4e3f39c4b92fb67495b0cf7
4
+ data.tar.gz: c1c23a29f68de3b6079ea88e0744bbaf5c9ca438b5f1e8154b72eadf330ccac7
5
5
  SHA512:
6
- metadata.gz: 5d49ba31b089bc450704c14d0d93f5b2a5c40519c4d324474fa6f8c27faacb8808f71c9f36f9c8baa519084b9f20e39b9569868504d061c422fa65fc3ed1e94e
7
- data.tar.gz: a11d6dbc2323b7e9e0aa92aa7bbdf8b67a2cbc1329ff637e4a4cfd047191ea347c58ae40bb6a5f0a4cfc614cf6e7c3561e9de629c1172e18c930534cdf5a7f25
6
+ metadata.gz: e3b09f9314ca321522b7a599231274e4685255f85457eb9b7466047941db5e22c8907d2d607c3b7d40e26b1d381423841291e269423545da2ea2345b734f0b82
7
+ data.tar.gz: ab1b340d0812134021d7776016e3cfb51358c2ecbe85b57e5f2943b07ec61608cae635ae6525390e16d6b7003d96638d859fc452572d7047700c0b3c1378afce
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,5 +1,5 @@
1
1
  module Rex
2
2
  module Text
3
- VERSION = "0.2.48"
3
+ VERSION = "0.2.50"
4
4
  end
5
5
  end
@@ -56,13 +56,13 @@ class WrappedTable
56
56
  #
57
57
  # The text to affix to the end of the table.
58
58
  #
59
- # Sortindex
59
+ # SortIndex
60
60
  #
61
61
  # The column to sort the table on, -1 disables sorting.
62
62
  #
63
63
  # ColProps
64
64
  #
65
- # A hash specifying column MaxWidth, Stylers, and Formatters.
65
+ # A hash specifying column Width, Stylers, and Formatters.
66
66
  #
67
67
  def initialize(opts = {})
68
68
  self.header = opts['Header']
@@ -85,10 +85,11 @@ class WrappedTable
85
85
  # Default column properties
86
86
  self.columns.length.times { |idx|
87
87
  self.colprops[idx] = {}
88
- self.colprops[idx]['MaxWidth'] = self.columns[idx].length
88
+ self.colprops[idx]['Width'] = nil
89
89
  self.colprops[idx]['WordWrap'] = true
90
90
  self.colprops[idx]['Stylers'] = []
91
91
  self.colprops[idx]['Formatters'] = []
92
+ self.colprops[idx]['ColumnStylers'] = []
92
93
  }
93
94
 
94
95
  # ensure all our internal state gets updated with the given rows by
@@ -112,20 +113,28 @@ class WrappedTable
112
113
  # Converts table contents to a string.
113
114
  #
114
115
  def to_s
116
+ sort_rows
117
+
118
+ # Loop over and style columns
119
+ styled_columns = columns.map.with_index { |col, idx| style_table_column_headers(col, idx) }
120
+ # Loop over and style rows that are visible to the user
121
+ styled_rows = rows.select { |row| row_visible(row) }
122
+ .map! { |row| row.map.with_index { |cell, index| style_table_field(cell, index) } }
123
+
124
+ optimal_widths = calculate_optimal_widths(styled_columns, styled_rows)
125
+
115
126
  str = prefix.dup
116
127
  str << header_to_s || ''
117
- str << columns_to_s || ''
128
+ str << columns_to_s(styled_columns, optimal_widths) || ''
118
129
  str << hr_to_s || ''
119
130
 
120
- sort_rows
121
- rows.each { |row|
122
- if (is_hr(row))
131
+ styled_rows.each { |row|
132
+ if is_hr(row)
123
133
  str << hr_to_s
124
134
  else
125
- str << row_to_s(row) if row_visible(row)
135
+ str << row_to_s(row, optimal_widths)
126
136
  end
127
137
  }
128
-
129
138
  str << postfix
130
139
 
131
140
  return str
@@ -135,6 +144,8 @@ class WrappedTable
135
144
  # Converts table contents to a csv
136
145
  #
137
146
  def to_csv
147
+ sort_rows
148
+
138
149
  str = ''
139
150
  str << ( columns.join(",") + "\n" )
140
151
  rows.each { |row|
@@ -185,11 +196,6 @@ class WrappedTable
185
196
  formatted_fields = fields.map.with_index { |field, idx|
186
197
  field = format_table_field(field, idx)
187
198
 
188
- if (colprops[idx]['MaxWidth'] < display_width(field))
189
- old = colprops[idx]['MaxWidth']
190
- colprops[idx]['MaxWidth'] = display_width(field)
191
- end
192
-
193
199
  field
194
200
  }
195
201
 
@@ -333,7 +339,7 @@ protected
333
339
  #
334
340
  def row_visible(row)
335
341
  return true if self.scterm.nil?
336
- row_to_s(row).match(self.scterm)
342
+ row.join(' ').match(self.scterm)
337
343
  end
338
344
 
339
345
  #
@@ -354,8 +360,7 @@ protected
354
360
  #
355
361
  # Converts the columns to a string.
356
362
  #
357
- def columns_to_s # :nodoc:
358
- optimal_widths = calculate_optimal_widths
363
+ def columns_to_s(columns, optimal_widths) # :nodoc:
359
364
  values_as_chunks = chunk_values(columns, optimal_widths)
360
365
  result = chunks_to_s(values_as_chunks, optimal_widths)
361
366
 
@@ -389,9 +394,7 @@ protected
389
394
  #
390
395
  # Converts a row to a string.
391
396
  #
392
- def row_to_s(row) # :nodoc:
393
- row = row.each_with_index.map { |cell, index| style_table_field(cell, index) }
394
- optimal_widths = calculate_optimal_widths
397
+ def row_to_s(row, optimal_widths) # :nodoc:
395
398
  values_as_chunks = chunk_values(row, optimal_widths)
396
399
  chunks_to_s(values_as_chunks, optimal_widths)
397
400
  end
@@ -567,12 +570,26 @@ protected
567
570
  without_extra_column
568
571
  end
569
572
 
570
- def calculate_optimal_widths
571
- # Calculate the minimum width each column can be. This is dictated by the user.
573
+ def calculate_optimal_widths(styled_columns, styled_rows)
574
+ total_columns = self.colprops.length
575
+ # Calculate the display width metadata, i.e. the size of the longest strings in the table
576
+ display_width_metadata = Array.new(total_columns) { {} }
577
+ [[styled_columns], styled_rows].each do |group|
578
+ group.each do |row|
579
+ row.each.with_index do |cell, column_index|
580
+ metadata = display_width_metadata[column_index]
581
+ cell_display_width = display_width(cell)
582
+ if cell_display_width > (metadata[:max_display_width] || 0)
583
+ metadata[:max_display_width] = cell_display_width
584
+ end
585
+ end
586
+ end
587
+ end
588
+
589
+ # Calculate the sizes set by the user
572
590
  user_influenced_column_widths = colprops.map do |colprop|
573
- if colprop['WordWrap'] == false
574
- colprop['MaxWidth']
575
- raise 'Not implemented'
591
+ if colprop['Width']
592
+ colprop['Width']
576
593
  else
577
594
  nil
578
595
  end
@@ -583,15 +600,16 @@ protected
583
600
  remaining_column_calculations = user_influenced_column_widths.select(&:nil?).count
584
601
 
585
602
  # Calculate the initial widths, which will need an additional refinement to reallocate surplus space
586
- naive_optimal_width_calculations = colprops.map.with_index do |colprop, index|
603
+ naive_optimal_width_calculations = display_width_metadata.map.with_index do |display_size, index|
587
604
  shared_column_width = available_space / [remaining_column_calculations, 1].max
588
605
  remaining_column_calculations -= 1
589
606
 
607
+ # Preference the user defined widths first
590
608
  if user_influenced_column_widths[index]
591
609
  { width: user_influenced_column_widths[index], wrapped: false }
592
- elsif colprop['MaxWidth'] < shared_column_width
593
- available_space -= colprop['MaxWidth']
594
- { width: colprop['MaxWidth'], wrapped: false }
610
+ elsif display_size[:max_display_width] < shared_column_width
611
+ available_space -= display_size[:max_display_width]
612
+ { width: display_size[:max_display_width], wrapped: false }
595
613
  else
596
614
  available_space -= shared_column_width
597
615
  { width: shared_column_width, wrapped: true }
@@ -608,7 +626,7 @@ protected
608
626
  revisiting_column_counts -= 1
609
627
 
610
628
  if naive_width[:wrapped]
611
- max_width = colprops[index]['MaxWidth']
629
+ max_width = display_width_metadata[index][:max_display_width]
612
630
  if max_width < (naive_width[:width] + additional_column_width)
613
631
  surplus_width -= max_width - naive_width[:width]
614
632
  max_width
@@ -638,6 +656,16 @@ protected
638
656
  str_cp
639
657
  end
640
658
 
659
+ def style_table_column_headers(str, idx)
660
+ str_cp = str.dup
661
+
662
+ colprops[idx]['ColumnStylers'].each do |s|
663
+ str_cp = s.style(str_cp)
664
+ end
665
+
666
+ str_cp
667
+ end
668
+
641
669
  def style_table_field(str, idx)
642
670
  str_cp = str.dup
643
671
 
@@ -652,4 +680,3 @@ end
652
680
 
653
681
  end
654
682
  end
655
-
data/lib/rex/text.rb CHANGED
@@ -110,6 +110,8 @@ module Rex
110
110
  # @param [String] str
111
111
  # @return [Integer]
112
112
  def self.display_width(str)
113
+ return 0 if str.nil?
114
+
113
115
  str.gsub(COLOR_CODES_REGEX, '').length
114
116
  end
115
117
 
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rex-text
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.48
4
+ version: 0.2.50
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -93,7 +93,7 @@ cert_chain:
93
93
  EknWpNgVhohbot1lfVAMmIhdtOVaRVcQQixWPwprDj/ydB8ryDMDosIMcw+fkoXU
94
94
  9GJsSaSRRYQ9UUkVL27b64okU8D48m8=
95
95
  -----END CERTIFICATE-----
96
- date: 2023-01-31 00:00:00.000000000 Z
96
+ date: 2023-03-07 00:00:00.000000000 Z
97
97
  dependencies:
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: rake
metadata.gz.sig CHANGED
Binary file