rex-text 0.2.41 → 0.2.44
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/rex/text/color.rb +1 -0
- data/lib/rex/text/hex.rb +13 -42
- data/lib/rex/text/lang.rb +16 -16
- data/lib/rex/text/version.rb +1 -1
- data/lib/rex/text/wrapped_table.rb +129 -11
- data/lib/rex/text.rb +15 -0
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b88966aea3c2991faabd788caf7b9141968550554530da585e6cb46207c33d64
|
4
|
+
data.tar.gz: 233562b44e969d9a210695571a3aa84fcd4c4d84a6b0d22846696f84ff67a1d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6cd18682c4ffcaedc3c3177f27c42e93b4009cce7316090d3a64f84207895af48393f8cd431bd062fcc5c14f10241ad5537b464e2c5484bc1c513a4ed7d76502
|
7
|
+
data.tar.gz: 29cc99e565a56b899e43f8f9312ab9520abb3838ee68d8d3702de6ee13f080bc1929401837a0a32df3e00e29f673ae3d5aeee880e765fcf2f1b5727f60dfea76
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/rex/text/color.rb
CHANGED
data/lib/rex/text/hex.rb
CHANGED
@@ -127,51 +127,22 @@ module Rex
|
|
127
127
|
# Converts a string to a hex version with wrapping support
|
128
128
|
#
|
129
129
|
def self.hexify(str, col = DefaultWrap, line_start = '', line_end = '', buf_start = '', buf_end = '')
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
# Go through each byte in the string
|
136
|
-
str.each_byte { |byte|
|
137
|
-
count += 1
|
138
|
-
append = ''
|
139
|
-
|
140
|
-
# If this is a new line, prepend with the
|
141
|
-
# line start text
|
142
|
-
if (new_line == true)
|
143
|
-
append << line_start
|
144
|
-
new_line = false
|
145
|
-
end
|
146
|
-
|
147
|
-
# Append the hexified version of the byte
|
148
|
-
append << sprintf("\\x%.2x", byte)
|
149
|
-
cur += append.length
|
150
|
-
|
151
|
-
# If we're about to hit the column or have gone past it,
|
152
|
-
# time to finish up this line
|
153
|
-
if ((cur + line_end.length >= col) or (cur + buf_end.length >= col))
|
154
|
-
new_line = true
|
155
|
-
cur = 0
|
130
|
+
if col < line_start.length + 4 + line_end.length
|
131
|
+
# raise an exception
|
132
|
+
raise ArgumentError.new('insufficient column width')
|
133
|
+
end
|
156
134
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
135
|
+
ret = buf_start.dup
|
136
|
+
ret << line_start if ret.end_with?("\n")
|
137
|
+
str.each_char do |char|
|
138
|
+
# "\x##".length is 4, check if we're going over the wrap boundary
|
139
|
+
if (ret.split("\n").last || '').length + 4 + line_end.length > col
|
140
|
+
ret << "#{line_end}\n#{line_start}"
|
164
141
|
end
|
165
|
-
|
166
|
-
output << append
|
167
|
-
}
|
168
|
-
|
169
|
-
# If we were in the middle of a line, finish the buffer at this point
|
170
|
-
if (new_line == false)
|
171
|
-
output << buf_end + "\n"
|
142
|
+
ret << "\\x" << char.unpack('H*')[0]
|
172
143
|
end
|
173
|
-
|
174
|
-
|
144
|
+
ret << "\n" if ret.split("\n").last.length + buf_end.length > col
|
145
|
+
ret << "#{buf_end}\n"
|
175
146
|
end
|
176
147
|
|
177
148
|
#
|
data/lib/rex/text/lang.rb
CHANGED
@@ -29,13 +29,14 @@ module Rex
|
|
29
29
|
|
30
30
|
def self.to_csharp(str, wrap = DefaultWrap, name = "buf")
|
31
31
|
ret = "byte[] #{name} = new byte[#{str.length}] {"
|
32
|
-
|
33
|
-
|
34
|
-
ret << "\n" if
|
35
|
-
ret << "0x" <<
|
32
|
+
str.each_char do |char|
|
33
|
+
# "0x##,".length is 5, check if we're going over the wrap boundary
|
34
|
+
ret << "\n" if ret.split("\n").last.length + 5 > wrap
|
35
|
+
ret << "0x" << char.unpack('H*')[0] << ","
|
36
36
|
end
|
37
|
-
ret = ret[0..ret.length-2] #cut off last comma
|
38
|
-
ret << "
|
37
|
+
ret = ret[0..ret.length - 2] unless str.empty? # cut off last comma
|
38
|
+
ret << "\n" if ret.split("\n").last.length + 2 > wrap
|
39
|
+
ret << "};\n"
|
39
40
|
end
|
40
41
|
|
41
42
|
#
|
@@ -43,21 +44,21 @@ module Rex
|
|
43
44
|
#
|
44
45
|
def self.to_golang(str, wrap = DefaultWrap, name = "buf")
|
45
46
|
ret = "#{name} := []byte{"
|
46
|
-
|
47
|
-
|
48
|
-
ret << "\n" if
|
49
|
-
ret << "0x" <<
|
47
|
+
str.each_char do |char|
|
48
|
+
# "0x##,".length is 5, check if we're going over the wrap boundary
|
49
|
+
ret << "\n" if ret.split("\n").last.length + 5 > wrap
|
50
|
+
ret << "0x" << char.unpack('H*')[0] << ","
|
50
51
|
end
|
51
|
-
ret = ret[0..ret.length-
|
52
|
-
ret << "
|
53
|
-
|
52
|
+
ret = ret[0..ret.length - 2] unless str.empty? # cut off last comma
|
53
|
+
ret << "\n" if ret.split("\n").last.length + 2 > wrap
|
54
|
+
ret << "};\n"
|
54
55
|
end
|
55
|
-
|
56
|
+
|
56
57
|
#
|
57
58
|
# Creates a golang style comment
|
58
59
|
#
|
59
60
|
def self.to_golang_comment(str, wrap = DefaultWrap)
|
60
|
-
return "/*\n" + wordwrap(str, 0, wrap, '', '') + "*/\n"
|
61
|
+
return "/*\n" + wordwrap(str, 0, wrap, '', '') + "*/\n"
|
61
62
|
end
|
62
63
|
|
63
64
|
#
|
@@ -181,6 +182,5 @@ module Rex
|
|
181
182
|
return wordwrap(str, 0, wrap, '', '# ')
|
182
183
|
end
|
183
184
|
|
184
|
-
|
185
185
|
end
|
186
186
|
end
|
data/lib/rex/text/version.rb
CHANGED
@@ -390,6 +390,7 @@ protected
|
|
390
390
|
# Converts a row to a string.
|
391
391
|
#
|
392
392
|
def row_to_s(row) # :nodoc:
|
393
|
+
row = row.each_with_index.map { |cell, index| style_table_field(cell, index) }
|
393
394
|
optimal_widths = calculate_optimal_widths
|
394
395
|
values_as_chunks = chunk_values(row, optimal_widths)
|
395
396
|
chunks_to_s(values_as_chunks, optimal_widths)
|
@@ -401,17 +402,134 @@ protected
|
|
401
402
|
# widths. For now it simply returns the string's length.
|
402
403
|
#
|
403
404
|
def display_width(str)
|
404
|
-
str
|
405
|
+
Rex::Text.display_width(str)
|
405
406
|
end
|
406
407
|
|
408
|
+
#
|
409
|
+
# Returns a string of color/formatting codes made up of the previously stored color_state
|
410
|
+
# e.g. if a `%blu` color code spans multiple lines this will return a string of `%blu` to be appended to
|
411
|
+
# the beginning of each row
|
412
|
+
#
|
413
|
+
# @param [Hash<String, String>] color_state tracks current color/formatting codes within table row
|
414
|
+
# @returns [String] Color code string such as `%blu%grn'
|
415
|
+
def color_code_string_for(color_state)
|
416
|
+
result = ''.dup
|
417
|
+
color_state.each do |_format, value|
|
418
|
+
if value.is_a?(Array)
|
419
|
+
result << value.uniq.join
|
420
|
+
else
|
421
|
+
result << value
|
422
|
+
end
|
423
|
+
end
|
424
|
+
result
|
425
|
+
end
|
426
|
+
|
427
|
+
# @returns [Hash<String, String>] The supported color codes from {Rex::Text::Color} grouped into sections
|
428
|
+
def color_code_groups
|
429
|
+
return @color_code_groups if @color_code_groups
|
430
|
+
|
431
|
+
@color_code_groups = {
|
432
|
+
foreground: %w[
|
433
|
+
%cya %red %grn %blu %yel %whi %mag %blk
|
434
|
+
%dred %dgrn %dblu %dyel %dcya %dwhi %dmag
|
435
|
+
],
|
436
|
+
background: %w[
|
437
|
+
%bgblu %bgyel %bggrn %bgmag %bgblk %bgred %bgcyn %bgwhi
|
438
|
+
],
|
439
|
+
decoration: %w[
|
440
|
+
%und %bld
|
441
|
+
],
|
442
|
+
clear: %w[
|
443
|
+
%clr
|
444
|
+
]
|
445
|
+
}
|
446
|
+
|
447
|
+
# Developer exception raised to ensure all color codes are accounted for. Verified via tests.
|
448
|
+
missing_color_codes = (Rex::Text::Color::SUPPORTED_FORMAT_CODES - @color_code_groups.values.flatten)
|
449
|
+
raise "Unsupported color codes #{missing_color_codes.join(', ')}" if missing_color_codes.any?
|
450
|
+
|
451
|
+
@color_code_groups
|
452
|
+
end
|
453
|
+
|
454
|
+
# Find the preceding color type and value of a given string
|
455
|
+
# @param [String] string A string such as '%bgyel etc'
|
456
|
+
# @returns [Array,nil] A tuple with the color type and value, or nil
|
457
|
+
def find_color_type_and_value(string)
|
458
|
+
color_code_groups.each do |color_type, color_values|
|
459
|
+
color_value = color_values.find { |color_value| string.start_with?(color_value) }
|
460
|
+
if color_value
|
461
|
+
return [color_type, color_value]
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
nil
|
466
|
+
end
|
467
|
+
|
468
|
+
#
|
469
|
+
# Takes an array of row values and an integer of optimal column width, loops over array and parses
|
470
|
+
# each string to gather color/formatting tags and handles those appropriately while not increasing the column width
|
471
|
+
#
|
472
|
+
# e.g. if a formatting "%blu" spans across multiple lines it needs to be added to the beginning off every following
|
473
|
+
# line, and each line will have a "%clr" added to the end of each row
|
474
|
+
#
|
475
|
+
# @param [Array<String>] values
|
476
|
+
# @param [Integer] optimal_widths
|
407
477
|
def chunk_values(values, optimal_widths)
|
408
478
|
# First split long strings into an array of chunks, where each chunk size is the calculated column width
|
409
479
|
values_as_chunks = values.each_with_index.map do |value, idx|
|
480
|
+
color_state = {}
|
410
481
|
column_width = optimal_widths[idx]
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
482
|
+
chunks = []
|
483
|
+
current_chunk = nil
|
484
|
+
chars = value.chars
|
485
|
+
char_index = 0
|
486
|
+
|
487
|
+
# Check if any color code(s) from previous the string need appended
|
488
|
+
while char_index < chars.length do
|
489
|
+
# If a new chunk has started, start the chunk with any previous color codes
|
490
|
+
if current_chunk.nil? && color_state.any?
|
491
|
+
current_chunk = color_code_string_for(color_state)
|
492
|
+
end
|
493
|
+
current_chunk ||= ''.dup
|
494
|
+
|
495
|
+
# Check if the remaining chars start with a color code such as %blu
|
496
|
+
color_type_and_value = chars[char_index] == '%' ? find_color_type_and_value(chars[char_index..].join) : nil
|
497
|
+
if color_type_and_value.nil?
|
498
|
+
current_chunk << chars[char_index]
|
499
|
+
char_index += 1
|
500
|
+
else
|
501
|
+
color_type, color_code = color_type_and_value
|
502
|
+
|
503
|
+
if color_type == :clear
|
504
|
+
color_state.clear
|
505
|
+
elsif color_type == :decoration
|
506
|
+
# Multiple decorations can be enabled
|
507
|
+
color_state[:decoration] ||= []
|
508
|
+
color_state[:decoration] << color_code
|
509
|
+
else
|
510
|
+
# There can only be one foreground or background color
|
511
|
+
color_state[color_type] = color_code
|
512
|
+
end
|
513
|
+
|
514
|
+
current_chunk << color_code
|
515
|
+
char_index += color_code.length
|
516
|
+
end
|
517
|
+
|
518
|
+
# If we've reached the final character of the string, or need to word wrap
|
519
|
+
# it's time to push the current chunk, and start a new row. Also discard
|
520
|
+
# any values that are purely colors and have no display_width
|
521
|
+
is_final_character = char_index >= chars.length
|
522
|
+
display_width = display_width(current_chunk)
|
523
|
+
if (is_final_character && display_width != 0) || display_width == column_width
|
524
|
+
if color_state.any? && !current_chunk.end_with?('%clr')
|
525
|
+
current_chunk << '%clr'
|
526
|
+
end
|
527
|
+
chunks.push(current_chunk)
|
528
|
+
current_chunk = nil
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
chunks
|
415
533
|
end
|
416
534
|
|
417
535
|
values_as_chunks
|
@@ -424,12 +542,13 @@ protected
|
|
424
542
|
line = ""
|
425
543
|
row_chunks.each_with_index do |chunk, idx|
|
426
544
|
column_width = optimal_widths[idx]
|
545
|
+
chunk_length_with_padding = column_width + (chunk.to_s.length - display_width(chunk.to_s))
|
427
546
|
|
428
547
|
if idx == 0
|
429
548
|
line << ' ' * indent
|
430
549
|
end
|
431
550
|
|
432
|
-
line << chunk.to_s.ljust(
|
551
|
+
line << chunk.to_s.ljust(chunk_length_with_padding)
|
433
552
|
line << ' ' * cellpad
|
434
553
|
end
|
435
554
|
|
@@ -519,13 +638,12 @@ protected
|
|
519
638
|
str_cp
|
520
639
|
end
|
521
640
|
|
522
|
-
def style_table_field(str,
|
641
|
+
def style_table_field(str, idx)
|
523
642
|
str_cp = str.dup
|
524
643
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
# end
|
644
|
+
colprops[idx]['Stylers'].each do |s|
|
645
|
+
str_cp = s.style(str_cp)
|
646
|
+
end
|
529
647
|
|
530
648
|
str_cp
|
531
649
|
end
|
data/lib/rex/text.rb
CHANGED
@@ -98,6 +98,21 @@ module Rex
|
|
98
98
|
end
|
99
99
|
|
100
100
|
|
101
|
+
# @return [Regexp] Matches a valid color code, i.e. "%blu,%yel,...etc"
|
102
|
+
COLOR_CODES_REGEX = /#{Regexp.union(Rex::Text::Color::SUPPORTED_FORMAT_CODES.compact).source}/
|
103
|
+
private_constant :COLOR_CODES_REGEX
|
104
|
+
|
105
|
+
#
|
106
|
+
# Function that aims to calculate the display width of the given string.
|
107
|
+
# In the future this will be aware of East Asian characters having different display
|
108
|
+
# widths. For now it simply returns the string's length ignoring color codes.
|
109
|
+
#
|
110
|
+
# @param [String] str
|
111
|
+
# @return [Integer]
|
112
|
+
def self.display_width(str)
|
113
|
+
str.gsub(COLOR_CODES_REGEX, '').length
|
114
|
+
end
|
115
|
+
|
101
116
|
#
|
102
117
|
# Convert 16-byte string to a GUID string
|
103
118
|
#
|
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.
|
4
|
+
version: 0.2.44
|
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: 2022-
|
96
|
+
date: 2022-09-02 00:00:00.000000000 Z
|
97
97
|
dependencies:
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
99
|
name: rake
|
metadata.gz.sig
CHANGED
Binary file
|