unisec 0.0.4 → 0.0.5

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: 207fef6efc641ecf3ba11879d368cd2c6ac54f4d7001d948428c32a67e992e05
4
- data.tar.gz: bec8d1577d59b146747a1346794df62ea7928feb47ca3c64e669636f91cdb9fa
3
+ metadata.gz: 0b6f74de3dc3d0f9aebac59ff68bc5731b7185e9e73e86e87477c23408900452
4
+ data.tar.gz: 910be7b95b71022f352cc6d612c7752fe2ea13a0e6e3dc89aca4566cb1879569
5
5
  SHA512:
6
- metadata.gz: cb406f1c0b27575d84b497d5cec9a994f05a33f816630ebacd5013594997394c5b5473575d1a241193bb1e586bd3a7510c80a7597d9995f35cbb0f5b09882987
7
- data.tar.gz: 994e93feae65577b462e85ac3450dbb4d8a7f6160d00f4a19fe21bae518de85846a2e4cb71668b7fee0c5afb2ea39932831d2e333e802ab048b6dbd5bd653cc1
6
+ metadata.gz: 47b730a884a30979be5968d90a30bc214ec93725383f20c48a02ec1090ce64e6043f95427c7ed79ebc31b3b4e1d3b66e01c7b0d63f936793f6c8eb008ce5f9fe
7
+ data.tar.gz: be9ca5cc40baaf9cd56141a3a8e41f5709c6071d5e7797ebd64a1daf231671e6835c168bce53f540e72ead4f68fc93bfd2d211764ba474e1cd8a4ca1bf5e7a65
data/lib/unisec/bidi.rb CHANGED
@@ -129,6 +129,7 @@ module Unisec
129
129
  #
130
130
  # The light version displays only the spoof payload for easy piping with other commands.
131
131
  # @param light [Boolean] `true` = light display (displays only the spoof payload for easy piping with other commands), `false` (default) = full display.
132
+ # @return [String] CLI-ready output
132
133
  # @example
133
134
  # puts Unisec::Bidi::Spoof.new('noraj').display
134
135
  # # Target string: noraj
@@ -3,6 +3,7 @@
3
3
  require 'unisec/cli/bidi'
4
4
  require 'unisec/cli/confusables'
5
5
  require 'unisec/cli/hexdump'
6
+ require 'unisec/cli/normalization'
6
7
  require 'unisec/cli/properties'
7
8
  require 'unisec/cli/rugrep'
8
9
  require 'unisec/cli/size'
@@ -23,6 +24,7 @@ module Unisec
23
24
  register 'confusables randomize', Confusables::Randomize
24
25
  register 'grep', Grep
25
26
  register 'hexdump', Hexdump
27
+ register 'normalize', Normalize
26
28
  register 'properties char', Properties::Char
27
29
  register 'properties codepoints', Properties::Codepoints
28
30
  register 'properties list', Properties::List
@@ -17,6 +17,9 @@ module Unisec
17
17
  # UTF-16LE: 4100 4300 4300 4500 4900 5300
18
18
  # UTF-32BE: 00000041 00000043 00000043 00000045 00000049 00000053
19
19
  # UTF-32LE: 41000000 43000000 43000000 45000000 49000000 53000000
20
+ #
21
+ # $unisec hexdump "ACCEIS" --enc utf16le
22
+ # 4100 4300 4300 4500 4900 5300
20
23
  # ```
21
24
  class Hexdump < Dry::CLI::Command
22
25
  desc 'Hexdump in all Unicode encodings'
@@ -35,7 +38,7 @@ module Unisec
35
38
  puts Unisec::Hexdump.new(input).display
36
39
  else
37
40
  # using send() is safe here thanks to the value whitelist
38
- puts puts Unisec::Hexdump.send(options[:enc], input)
41
+ puts Unisec::Hexdump.send(options[:enc], input)
39
42
  end
40
43
  end
41
44
  end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry/cli'
4
+ require 'unisec'
5
+ require 'unisec/utils'
6
+
7
+ module Unisec
8
+ module CLI
9
+ module Commands
10
+ # CLI sub-commands `unisec normalize xxx` for the class {Unisec::Normalization} from the lib.
11
+ #
12
+ # Command `unisec normalize "example"`
13
+ #
14
+ # Example:
15
+ #
16
+ # ```plaintext
17
+ # ➜ unisec normalize ẛ̣
18
+ # Original: ẛ̣
19
+ # U+1E9B U+0323
20
+ # NFC: ẛ̣
21
+ # U+1E9B U+0323
22
+ # NFKC: ṩ
23
+ # U+1E69
24
+ # NFD: ẛ̣
25
+ # U+017F U+0323 U+0307
26
+ # NFKD: ṩ
27
+ # U+0073 U+0323 U+0307
28
+ #
29
+ # ➜ unisec normalize ẛ̣ --form nfkd
30
+ # ṩ
31
+ # ```
32
+ class Normalize < Dry::CLI::Command
33
+ desc 'Normalize in all forms'
34
+
35
+ argument :input, required: true,
36
+ desc: 'String input. Read from STDIN if equal to -.'
37
+
38
+ option :form, default: nil, values: %w[nfc nfkc nfd nfkd],
39
+ desc: 'Output only in the specified normalization form.'
40
+
41
+ # Normalize in all forms
42
+ # @param input [String] Input string to normalize
43
+ def call(input: nil, **options)
44
+ input = $stdin.read.chomp if input == '-'
45
+ if options[:form].nil?
46
+ puts Unisec::Normalization.new(input).display
47
+ else
48
+ # using send() is safe here thanks to the value whitelist
49
+ puts Unisec::Normalization.send(options[:form], input)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -86,6 +86,7 @@ module Unisec
86
86
  end
87
87
 
88
88
  # Display a CLI-friendly output summurizing the hexdump in all Unicode encodings
89
+ # @return [String] CLI-ready output
89
90
  # @example
90
91
  # puts Unisec::Hexdump.new('K').display # =>
91
92
  # # UTF-8: e2 84 aa
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ctf_party'
4
+
5
+ module Unisec
6
+ # Normalization Forms
7
+ class Normalization
8
+ # Original input
9
+ # @return [String] untouched input
10
+ attr_reader :original
11
+
12
+ # Normalization Form C (NFC) - Canonical Decomposition, followed by Canonical Composition
13
+ # @return [String] input normalized with NFC
14
+ attr_reader :nfc
15
+
16
+ # Normalization Form KC (NFKC) - Compatibility Decomposition, followed by Canonical Composition
17
+ # @return [String] input normalized with NFKC
18
+ attr_reader :nfkc
19
+
20
+ # Normalization Form D (NFD) - Canonical Decomposition
21
+ # @return [String] input normalized with NFD
22
+ attr_reader :nfd
23
+
24
+ # Normalization Form KD (NFKD) - Compatibility Decomposition
25
+ # @return [String] input normalized with NFKD
26
+ attr_reader :nfkd
27
+
28
+ # Generate all normilzation forms for a given input
29
+ # @param str [String] the target string
30
+ # @return [nil]
31
+ def initialize(str)
32
+ @original = str
33
+ @nfc = Normalization.nfc(str)
34
+ @nfkc = Normalization.nfkc(str)
35
+ @nfd = Normalization.nfd(str)
36
+ @nfkd = Normalization.nfkd(str)
37
+ end
38
+
39
+ # Normalization Form C (NFC) - Canonical Decomposition, followed by Canonical Composition
40
+ # @param str [String] the target string
41
+ # @return [String] input normalized with NFC
42
+ def self.nfc(str)
43
+ str.unicode_normalize(:nfc)
44
+ end
45
+
46
+ # Normalization Form KC (NFKC) - Compatibility Decomposition, followed by Canonical Composition
47
+ # @param str [String] the target string
48
+ # @return [String] input normalized with NFKC
49
+ def self.nfkc(str)
50
+ str.unicode_normalize(:nfkc)
51
+ end
52
+
53
+ # Normalization Form D (NFD) - Canonical Decomposition
54
+ # @param str [String] the target string
55
+ # @return [String] input normalized with NFD
56
+ def self.nfd(str)
57
+ str.unicode_normalize(:nfd)
58
+ end
59
+
60
+ # Normalization Form KD (NFKD) - Compatibility Decomposition
61
+ # @param str [String] the target string
62
+ # @return [String] input normalized with NFKD
63
+ def self.nfkd(str)
64
+ str.unicode_normalize(:nfkd)
65
+ end
66
+
67
+ # Display a CLI-friendly output summurizing all normalization forms
68
+ # @return [String] CLI-ready output
69
+ # @example
70
+ # puts Unisec::Normalization.new("\u{1E9B 0323}").display
71
+ # # =>
72
+ # # Original: ẛ̣
73
+ # # U+1E9B U+0323
74
+ # # NFC: ẛ̣
75
+ # # U+1E9B U+0323
76
+ # # NFKC: ṩ
77
+ # # U+1E69
78
+ # # NFD: ẛ̣
79
+ # # U+017F U+0323 U+0307
80
+ # # NFKD: ṩ
81
+ # # U+0073 U+0323 U+0307
82
+ def display
83
+ colorize = lambda { |form_title, form_attr|
84
+ "#{Paint[form_title.to_s, :underline,
85
+ :bold]}: #{form_attr}\n #{Paint[Unisec::Properties.chars2codepoints(form_attr), :red]}\n"
86
+ }
87
+ colorize.call('Original', @original) +
88
+ colorize.call('NFC', @nfc) +
89
+ colorize.call('NFKC', @nfkc) +
90
+ colorize.call('NFD', @nfd) +
91
+ colorize.call('NFKD', @nfkd)
92
+ end
93
+ end
94
+ end
@@ -102,6 +102,7 @@ module Unisec
102
102
  # Display a CLI-friendly output summurizing everithing about the surrogates:
103
103
  # the corresponding character, code point, high and low surrogates
104
104
  # (each displayed as hexadecimal, decimal and binary).
105
+ # @return [String] CLI-ready output
105
106
  # @example
106
107
  # surr = Unisec::Surrogates.new(128169)
107
108
  # puts surr.display # =>
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Unisec
4
4
  # Version of unisec library and app
5
- VERSION = '0.0.4'
5
+ VERSION = '0.0.5'
6
6
  end
@@ -72,19 +72,19 @@ module Unisec
72
72
  # # …
73
73
  def self.display # rubocop:disable Metrics/AbcSize
74
74
  data = versions
75
- display = ->(node) { puts Paint[data[node][:label], :red, :bold].ljust(44) + " #{data[node][:version]}" }
76
- puts Paint['Unicode:', :underline]
77
- display.call(:ruby_unicode)
78
- display.call(:twittercldr_unicode)
79
- display.call(:unicodeconfusable_unicode)
80
- display.call(:twittercldr_icu)
81
- display.call(:twittercldr_cldr)
82
- display.call(:ruby_unicode_emoji)
83
- display.call(:ucd_derivedname)
84
- puts Paint["\nGems:", :underline]
85
- display.call(:unisec)
86
- display.call(:twittercldr)
87
- display.call(:unicodeconfusable)
75
+ colorize = ->(node) { Paint[data[node][:label], :red, :bold].ljust(44) + " #{data[node][:version]}\n" }
76
+ Paint["Unicode:\n", :underline] +
77
+ colorize.call(:ruby_unicode) +
78
+ colorize.call(:twittercldr_unicode) +
79
+ colorize.call(:unicodeconfusable_unicode) +
80
+ colorize.call(:twittercldr_icu) +
81
+ colorize.call(:twittercldr_cldr) +
82
+ colorize.call(:ruby_unicode_emoji) +
83
+ colorize.call(:ucd_derivedname) +
84
+ Paint["\nGems:\n", :underline] +
85
+ colorize.call(:unisec) +
86
+ colorize.call(:twittercldr) +
87
+ colorize.call(:unicodeconfusable)
88
88
  end
89
89
  end
90
90
  end
data/lib/unisec.rb CHANGED
@@ -5,6 +5,7 @@ require 'unisec/version'
5
5
  require 'unisec/bidi'
6
6
  require 'unisec/confusables'
7
7
  require 'unisec/hexdump'
8
+ require 'unisec/normalization'
8
9
  require 'unisec/properties'
9
10
  require 'unisec/rugrep'
10
11
  require 'unisec/size'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unisec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre ZANNI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-23 00:00:00.000000000 Z
11
+ date: 2024-02-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ctf-party
@@ -88,7 +88,7 @@ dependencies:
88
88
  version: '1.9'
89
89
  description: 'Toolkit for security research manipulating Unicode: confusables, homoglyphs,
90
90
  hexdump, code point, UTF-8, UTF-16, UTF-32, properties, regexp search, size, grapheme,
91
- surrogates, version, ICU, CLDR, UCD'
91
+ surrogates, version, ICU, CLDR, UCD, BiDi, normalization'
92
92
  email: alexandre.zanni@europe.com
93
93
  executables:
94
94
  - unisec
@@ -104,6 +104,7 @@ files:
104
104
  - lib/unisec/cli/cli.rb
105
105
  - lib/unisec/cli/confusables.rb
106
106
  - lib/unisec/cli/hexdump.rb
107
+ - lib/unisec/cli/normalization.rb
107
108
  - lib/unisec/cli/properties.rb
108
109
  - lib/unisec/cli/rugrep.rb
109
110
  - lib/unisec/cli/size.rb
@@ -111,6 +112,7 @@ files:
111
112
  - lib/unisec/cli/versions.rb
112
113
  - lib/unisec/confusables.rb
113
114
  - lib/unisec/hexdump.rb
115
+ - lib/unisec/normalization.rb
114
116
  - lib/unisec/properties.rb
115
117
  - lib/unisec/rugrep.rb
116
118
  - lib/unisec/size.rb