sass-embedded 1.6.2 → 1.83.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +9 -3
  3. data/exe/sass +13 -0
  4. data/ext/sass/Rakefile +352 -76
  5. data/ext/sass/embedded_sass_pb.rb +61 -0
  6. data/ext/sass/expand-archive.ps1 +1 -0
  7. data/ext/sass/package.json +1 -1
  8. data/lib/sass/calculation_value/calculation_operation.rb +49 -0
  9. data/lib/sass/calculation_value.rb +22 -0
  10. data/lib/sass/canonicalize_context.rb +25 -0
  11. data/lib/sass/compile_result.rb +3 -2
  12. data/lib/sass/compiler/channel.rb +68 -0
  13. data/lib/sass/compiler/connection.rb +89 -0
  14. data/lib/sass/compiler/dispatcher.rb +116 -0
  15. data/lib/sass/{embedded → compiler}/host/function_registry.rb +31 -34
  16. data/lib/sass/compiler/host/importer_registry.rb +141 -0
  17. data/lib/sass/compiler/host/logger_registry.rb +80 -0
  18. data/lib/sass/compiler/host/protofier.rb +360 -0
  19. data/lib/sass/compiler/host/structifier.rb +37 -0
  20. data/lib/sass/compiler/host.rb +226 -0
  21. data/lib/sass/{embedded → compiler}/varint.rb +9 -5
  22. data/lib/sass/compiler.rb +212 -0
  23. data/lib/sass/elf.rb +222 -0
  24. data/lib/sass/embedded/version.rb +2 -2
  25. data/lib/sass/embedded.rb +76 -204
  26. data/lib/sass/embedded_protocol.rb +10 -0
  27. data/lib/sass/exception.rb +74 -0
  28. data/lib/sass/fork_tracker.rb +51 -0
  29. data/lib/sass/logger/silent.rb +5 -3
  30. data/lib/sass/logger/source_location.rb +6 -5
  31. data/lib/sass/logger/source_span.rb +8 -7
  32. data/lib/sass/node_package_importer.rb +17 -0
  33. data/lib/sass/serializer.rb +30 -0
  34. data/lib/sass/value/argument_list.rb +13 -6
  35. data/lib/sass/value/boolean.rb +1 -1
  36. data/lib/sass/value/calculation.rb +90 -0
  37. data/lib/sass/value/color/channel.rb +79 -0
  38. data/lib/sass/value/color/conversions.rb +473 -0
  39. data/lib/sass/value/color/gamut_map_method/clip.rb +45 -0
  40. data/lib/sass/value/color/gamut_map_method/local_minde.rb +94 -0
  41. data/lib/sass/value/color/gamut_map_method.rb +45 -0
  42. data/lib/sass/value/color/interpolation_method.rb +51 -0
  43. data/lib/sass/value/color/space/a98_rgb.rb +57 -0
  44. data/lib/sass/value/color/space/display_p3.rb +57 -0
  45. data/lib/sass/value/color/space/hsl.rb +65 -0
  46. data/lib/sass/value/color/space/hwb.rb +70 -0
  47. data/lib/sass/value/color/space/lab.rb +77 -0
  48. data/lib/sass/value/color/space/lch.rb +53 -0
  49. data/lib/sass/value/color/space/lms.rb +129 -0
  50. data/lib/sass/value/color/space/oklab.rb +66 -0
  51. data/lib/sass/value/color/space/oklch.rb +54 -0
  52. data/lib/sass/value/color/space/prophoto_rgb.rb +59 -0
  53. data/lib/sass/value/color/space/rec2020.rb +69 -0
  54. data/lib/sass/value/color/space/rgb.rb +52 -0
  55. data/lib/sass/value/color/space/srgb.rb +140 -0
  56. data/lib/sass/value/color/space/srgb_linear.rb +72 -0
  57. data/lib/sass/value/color/space/utils.rb +86 -0
  58. data/lib/sass/value/color/space/xyz_d50.rb +100 -0
  59. data/lib/sass/value/color/space/xyz_d65.rb +57 -0
  60. data/lib/sass/value/color/space.rb +198 -0
  61. data/lib/sass/value/color.rb +538 -163
  62. data/lib/sass/value/function.rb +11 -16
  63. data/lib/sass/value/fuzzy_math.rb +24 -21
  64. data/lib/sass/value/list.rb +7 -7
  65. data/lib/sass/value/map.rb +6 -6
  66. data/lib/sass/value/mixin.rb +34 -0
  67. data/lib/sass/value/null.rb +1 -1
  68. data/lib/sass/value/number/unit.rb +7 -6
  69. data/lib/sass/value/number.rb +34 -26
  70. data/lib/sass/value/string.rb +9 -3
  71. data/lib/sass/value.rb +20 -16
  72. metadata +67 -103
  73. data/ext/sass/unzip.vbs +0 -13
  74. data/lib/sass/compile_error.rb +0 -28
  75. data/lib/sass/embedded/async.rb +0 -65
  76. data/lib/sass/embedded/channel.rb +0 -61
  77. data/lib/sass/embedded/compiler.rb +0 -60
  78. data/lib/sass/embedded/dispatcher.rb +0 -90
  79. data/lib/sass/embedded/host/importer_registry.rb +0 -107
  80. data/lib/sass/embedded/host/logger_registry.rb +0 -50
  81. data/lib/sass/embedded/host/value_protofier.rb +0 -241
  82. data/lib/sass/embedded/host.rb +0 -139
  83. data/lib/sass/embedded/protofier.rb +0 -78
  84. data/lib/sass/embedded/structifier.rb +0 -36
  85. data/lib/sass/script_error.rb +0 -6
@@ -0,0 +1,226 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'host/function_registry'
4
+ require_relative 'host/importer_registry'
5
+ require_relative 'host/logger_registry'
6
+ require_relative 'host/protofier'
7
+ require_relative 'host/structifier'
8
+
9
+ module Sass
10
+ class Compiler
11
+ # The {Host} class.
12
+ #
13
+ # It communicates with {Dispatcher} and handles the host logic.
14
+ class Host
15
+ def initialize(channel)
16
+ @channel = channel
17
+ end
18
+
19
+ def compile_request(path:,
20
+ source:,
21
+ importer:,
22
+ load_paths:,
23
+ syntax:,
24
+ url:,
25
+ charset:,
26
+ source_map:,
27
+ source_map_include_sources:,
28
+ style:,
29
+ functions:,
30
+ importers:,
31
+ alert_ascii:,
32
+ alert_color:,
33
+ fatal_deprecations:,
34
+ future_deprecations:,
35
+ logger:,
36
+ quiet_deps:,
37
+ silence_deprecations:,
38
+ verbose:)
39
+ alert_color = Exception.to_tty? if alert_color.nil?
40
+
41
+ @function_registry = FunctionRegistry.new(functions, alert_color:)
42
+ @importer_registry = ImporterRegistry.new(importers, load_paths, alert_color:)
43
+ @logger_registry = LoggerRegistry.new(logger)
44
+
45
+ compile_request = EmbeddedProtocol::InboundMessage::CompileRequest.new(
46
+ string: unless source.nil?
47
+ EmbeddedProtocol::InboundMessage::CompileRequest::StringInput.new(
48
+ source: source.to_str,
49
+ url: url&.to_s,
50
+ syntax: @importer_registry.syntax_to_proto(syntax),
51
+ importer: (@importer_registry.register(importer) unless importer.nil?)
52
+ )
53
+ end,
54
+ path: (File.absolute_path(path) unless path.nil?),
55
+ style: case style&.to_sym
56
+ when :expanded
57
+ EmbeddedProtocol::OutputStyle::EXPANDED
58
+ when :compressed
59
+ EmbeddedProtocol::OutputStyle::COMPRESSED
60
+ else
61
+ raise ArgumentError, 'style must be one of :expanded, :compressed'
62
+ end,
63
+ charset:,
64
+ source_map:,
65
+ source_map_include_sources:,
66
+ importers: @importer_registry.importers,
67
+ global_functions: @function_registry.global_functions,
68
+ alert_ascii:,
69
+ alert_color:,
70
+ fatal_deprecation: fatal_deprecations.map(&:to_s),
71
+ future_deprecation: future_deprecations.map(&:to_s),
72
+ quiet_deps:,
73
+ silent: logger == Logger.silent,
74
+ silence_deprecation: silence_deprecations.map(&:to_s),
75
+ verbose:
76
+ )
77
+
78
+ compile_response = await do
79
+ send_message(compile_request:)
80
+ end
81
+
82
+ oneof = compile_response.result
83
+ result = compile_response.public_send(oneof)
84
+ case oneof
85
+ when :failure
86
+ raise CompileError.new(
87
+ result.message,
88
+ result.formatted == '' ? nil : result.formatted,
89
+ result.stack_trace == '' ? nil : result.stack_trace,
90
+ result.span.nil? ? nil : Logger::SourceSpan.new(result.span),
91
+ compile_response.loaded_urls.to_a
92
+ )
93
+ when :success
94
+ CompileResult.new(
95
+ result.css,
96
+ result.source_map == '' ? nil : result.source_map,
97
+ compile_response.loaded_urls.to_a
98
+ )
99
+ else
100
+ raise ArgumentError, "Unknown CompileResponse.result #{result}"
101
+ end
102
+ end
103
+
104
+ def version_request
105
+ version_response = await0 do
106
+ send_message0(version_request: EmbeddedProtocol::InboundMessage::VersionRequest.new(
107
+ id:
108
+ ))
109
+ end
110
+
111
+ info = [
112
+ version_response.implementation_name,
113
+ version_response.implementation_version,
114
+ '(Sass Compiler)'
115
+ ]
116
+
117
+ case version_response.implementation_name
118
+ when 'dart-sass'
119
+ info << (CLI::COMMAND.first == 'node' ? '[JavaScript]' : '[Dart]')
120
+ end
121
+
122
+ info
123
+ end
124
+
125
+ def compile_response(message)
126
+ @result = message
127
+ @queue.close
128
+ end
129
+
130
+ def version_response(message)
131
+ @result = message
132
+ @queue.close
133
+ end
134
+
135
+ def error(message)
136
+ case message
137
+ when EmbeddedProtocol::ProtocolError
138
+ raise Errno::EPROTO, message.message
139
+ else
140
+ @error ||= message
141
+ @queue.close
142
+ end
143
+ end
144
+
145
+ def log_event(message)
146
+ @logger_registry.log(message)
147
+ end
148
+
149
+ def canonicalize_request(message)
150
+ send_message(canonicalize_response: @importer_registry.canonicalize(message))
151
+ end
152
+
153
+ def import_request(message)
154
+ send_message(import_response: @importer_registry.import(message))
155
+ end
156
+
157
+ def file_import_request(message)
158
+ send_message(file_import_response: @importer_registry.file_import(message))
159
+ end
160
+
161
+ def function_call_request(message)
162
+ send_message(function_call_response: @function_registry.function_call(message))
163
+ end
164
+
165
+ def receive_proto(proto)
166
+ @queue.push(proto)
167
+ end
168
+
169
+ private
170
+
171
+ def await0
172
+ listen do
173
+ yield
174
+
175
+ @queue.pop
176
+ end
177
+ end
178
+
179
+ def await
180
+ listen do
181
+ yield
182
+
183
+ while (proto = @queue.pop)
184
+ outbound_message = EmbeddedProtocol::OutboundMessage.decode(proto)
185
+ oneof = outbound_message.message
186
+ message = outbound_message.public_send(oneof)
187
+ public_send(oneof, message)
188
+ end
189
+ rescue Exception => e # rubocop:disable Lint/RescueException
190
+ @stream.error(e)
191
+ raise
192
+ end
193
+ end
194
+
195
+ def listen
196
+ @queue = Queue.new
197
+ @stream = @channel.stream(self)
198
+
199
+ yield
200
+
201
+ raise @error if @error
202
+
203
+ @result
204
+ ensure
205
+ @stream&.close
206
+ @queue&.close
207
+ end
208
+
209
+ def id
210
+ @stream.id
211
+ end
212
+
213
+ def send_message0(...)
214
+ inbound_message = EmbeddedProtocol::InboundMessage.new(...)
215
+ @stream.send_proto(0, EmbeddedProtocol::InboundMessage.encode(inbound_message))
216
+ end
217
+
218
+ def send_message(...)
219
+ inbound_message = EmbeddedProtocol::InboundMessage.new(...)
220
+ @stream.send_proto(id, EmbeddedProtocol::InboundMessage.encode(inbound_message))
221
+ end
222
+ end
223
+
224
+ private_constant :Host
225
+ end
226
+ end
@@ -1,13 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Embedded
4
+ class Compiler
5
5
  # The {Varint} module.
6
6
  #
7
7
  # It reads and writes varints.
8
8
  module Varint
9
9
  module_function
10
10
 
11
+ def length(value)
12
+ return 1 if value < 128
13
+
14
+ (value.bit_length + 6) / 7
15
+ end
16
+
11
17
  def read(readable)
12
18
  value = bits = 0
13
19
  loop do
@@ -20,13 +26,11 @@ module Sass
20
26
  end
21
27
 
22
28
  def write(writeable, value)
23
- bytes = []
24
29
  until value < 0x80
25
- bytes << (0x80 | (value & 0x7f))
30
+ writeable << ((value & 0x7f) | 0x80)
26
31
  value >>= 7
27
32
  end
28
- bytes << value
29
- writeable.write bytes.pack('C*')
33
+ writeable << value
30
34
  end
31
35
  end
32
36
 
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'canonicalize_context'
4
+ require_relative 'compile_result'
5
+ require_relative 'compiler/channel'
6
+ require_relative 'compiler/connection'
7
+ require_relative 'compiler/dispatcher'
8
+ require_relative 'compiler/host'
9
+ require_relative 'compiler/varint'
10
+ require_relative 'embedded/version'
11
+ require_relative 'embedded_protocol'
12
+ require_relative 'exception'
13
+ require_relative 'fork_tracker'
14
+ require_relative 'logger/silent'
15
+ require_relative 'logger/source_location'
16
+ require_relative 'logger/source_span'
17
+ require_relative 'node_package_importer'
18
+ require_relative 'serializer'
19
+ require_relative 'value'
20
+
21
+ module Sass
22
+ # A synchronous {Compiler}.
23
+ # Each compiler instance exposes the {#compile} and {#compile_string} methods within the lifespan of the compiler.
24
+ #
25
+ # @example
26
+ # sass = Sass::Compiler.new
27
+ # result = sass.compile_string('h1 { font-size: 40px; }')
28
+ # result = sass.compile('style.scss')
29
+ # sass.close
30
+ # @see https://sass-lang.com/documentation/js-api/classes/compiler/
31
+ class Compiler
32
+ def initialize
33
+ @channel = Channel.new(Dispatcher)
34
+ end
35
+
36
+ # Compiles the Sass file at +path+ to CSS.
37
+ # @param path [String]
38
+ # @param load_paths [Array<String>] Paths in which to look for stylesheets loaded by rules like
39
+ # {@use}[https://sass-lang.com/documentation/at-rules/use/] and {@import}[https://sass-lang.com/documentation/at-rules/import/].
40
+ # @param charset [Boolean] By default, if the CSS document contains non-ASCII characters, Sass adds a +@charset+
41
+ # declaration (in expanded output mode) or a byte-order mark (in compressed mode) to indicate its encoding to
42
+ # browsers or other consumers. If +charset+ is +false+, these annotations are omitted.
43
+ # @param source_map [Boolean] Whether or not Sass should generate a source map.
44
+ # @param source_map_include_sources [Boolean] Whether Sass should include the sources in the generated source map.
45
+ # @param style [Symbol] The OutputStyle of the compiled CSS.
46
+ # @param functions [Hash<String, Proc>] Additional built-in Sass functions that are available in all stylesheets.
47
+ # @param importers [Array<Object>] Custom importers that control how Sass resolves loads from rules like
48
+ # {@use}[https://sass-lang.com/documentation/at-rules/use/] and {@import}[https://sass-lang.com/documentation/at-rules/import/].
49
+ # @param alert_ascii [Boolean] If this is +true+, the compiler will exclusively use ASCII characters in its error
50
+ # and warning messages. Otherwise, it may use non-ASCII Unicode characters as well.
51
+ # @param alert_color [Boolean] If this is +true+, the compiler will use ANSI color escape codes in its error and
52
+ # warning messages. If it's +false+, it won't use these. If it's +nil+, the compiler will determine whether or
53
+ # not to use colors depending on whether the user is using an interactive terminal.
54
+ # @param fatal_deprecations [Array<String>] A set of deprecations to treat as fatal.
55
+ # @param future_deprecations [Array<String>] A set of future deprecations to opt into early.
56
+ # @param logger [Object] An object to use to handle warnings and/or debug messages from Sass.
57
+ # @param quiet_deps [Boolean] If this option is set to +true+, Sass won’t print warnings that are caused by
58
+ # dependencies. A “dependency” is defined as any file that’s loaded through +load_paths+ or +importer+.
59
+ # Stylesheets that are imported relative to the entrypoint are not considered dependencies.
60
+ # @param silence_deprecations [Array<String>] A set of active deprecations to ignore.
61
+ # @param verbose [Boolean] By default, Dart Sass will print only five instances of the same deprecation warning per
62
+ # compilation to avoid deluging users in console noise. If you set verbose to +true+, it will instead print every
63
+ # deprecation warning it encounters.
64
+ # @return [CompileResult]
65
+ # @raise [ArgumentError, CompileError, IOError]
66
+ # @see https://sass-lang.com/documentation/js-api/functions/compile/
67
+ def compile(path,
68
+ load_paths: [],
69
+
70
+ charset: true,
71
+ source_map: false,
72
+ source_map_include_sources: false,
73
+ style: :expanded,
74
+
75
+ functions: {},
76
+ importers: [],
77
+
78
+ alert_ascii: false,
79
+ alert_color: nil,
80
+ fatal_deprecations: [],
81
+ future_deprecations: [],
82
+ logger: nil,
83
+ quiet_deps: false,
84
+ silence_deprecations: [],
85
+ verbose: false)
86
+ raise ArgumentError, 'path must be set' if path.nil?
87
+
88
+ Host.new(@channel).compile_request(
89
+ path:,
90
+ source: nil,
91
+ importer: nil,
92
+ load_paths:,
93
+ syntax: nil,
94
+ url: nil,
95
+ charset:,
96
+ source_map:,
97
+ source_map_include_sources:,
98
+ style:,
99
+ functions:,
100
+ importers:,
101
+ alert_color:,
102
+ alert_ascii:,
103
+ fatal_deprecations:,
104
+ future_deprecations:,
105
+ logger:,
106
+ quiet_deps:,
107
+ silence_deprecations:,
108
+ verbose:
109
+ )
110
+ end
111
+
112
+ # Compiles a stylesheet whose contents is +source+ to CSS.
113
+ # @param source [String]
114
+ # @param importer [Object] The importer to use to handle loads that are relative to the entrypoint stylesheet.
115
+ # @param load_paths [Array<String>] Paths in which to look for stylesheets loaded by rules like
116
+ # {@use}[https://sass-lang.com/documentation/at-rules/use/] and {@import}[https://sass-lang.com/documentation/at-rules/import/].
117
+ # @param syntax [Symbol] The Syntax to use to parse the entrypoint stylesheet.
118
+ # @param url [String] The canonical URL of the entrypoint stylesheet. If this is passed along with +importer+, it's
119
+ # used to resolve relative loads in the entrypoint stylesheet.
120
+ # @param charset [Boolean] By default, if the CSS document contains non-ASCII characters, Sass adds a +@charset+
121
+ # declaration (in expanded output mode) or a byte-order mark (in compressed mode) to indicate its encoding to
122
+ # browsers or other consumers. If +charset+ is +false+, these annotations are omitted.
123
+ # @param source_map [Boolean] Whether or not Sass should generate a source map.
124
+ # @param source_map_include_sources [Boolean] Whether Sass should include the sources in the generated source map.
125
+ # @param style [Symbol] The OutputStyle of the compiled CSS.
126
+ # @param functions [Hash<String, Proc>] Additional built-in Sass functions that are available in all stylesheets.
127
+ # @param importers [Array<Object>] Custom importers that control how Sass resolves loads from rules like
128
+ # {@use}[https://sass-lang.com/documentation/at-rules/use/] and {@import}[https://sass-lang.com/documentation/at-rules/import/].
129
+ # @param alert_ascii [Boolean] If this is +true+, the compiler will exclusively use ASCII characters in its error
130
+ # and warning messages. Otherwise, it may use non-ASCII Unicode characters as well.
131
+ # @param alert_color [Boolean] If this is +true+, the compiler will use ANSI color escape codes in its error and
132
+ # warning messages. If it's +false+, it won't use these. If it's +nil+, the compiler will determine whether or
133
+ # not to use colors depending on whether the user is using an interactive terminal.
134
+ # @param fatal_deprecations [Array<String>] A set of deprecations to treat as fatal.
135
+ # @param future_deprecations [Array<String>] A set of future deprecations to opt into early.
136
+ # @param logger [Object] An object to use to handle warnings and/or debug messages from Sass.
137
+ # @param quiet_deps [Boolean] If this option is set to +true+, Sass won’t print warnings that are caused by
138
+ # dependencies. A “dependency” is defined as any file that’s loaded through +load_paths+ or +importer+.
139
+ # Stylesheets that are imported relative to the entrypoint are not considered dependencies.
140
+ # @param silence_deprecations [Array<String>] A set of active deprecations to ignore.
141
+ # @param verbose [Boolean] By default, Dart Sass will print only five instances of the same deprecation warning per
142
+ # compilation to avoid deluging users in console noise. If you set verbose to +true+, it will instead print every
143
+ # deprecation warning it encounters.
144
+ # @return [CompileResult]
145
+ # @raise [ArgumentError, CompileError, IOError]
146
+ # @see https://sass-lang.com/documentation/js-api/functions/compilestring/
147
+ def compile_string(source,
148
+ importer: nil,
149
+ load_paths: [],
150
+ syntax: :scss,
151
+ url: nil,
152
+
153
+ charset: true,
154
+ source_map: false,
155
+ source_map_include_sources: false,
156
+ style: :expanded,
157
+
158
+ functions: {},
159
+ importers: [],
160
+
161
+ alert_ascii: false,
162
+ alert_color: nil,
163
+ fatal_deprecations: [],
164
+ future_deprecations: [],
165
+ logger: nil,
166
+ quiet_deps: false,
167
+ silence_deprecations: [],
168
+ verbose: false)
169
+ raise ArgumentError, 'source must be set' if source.nil?
170
+
171
+ Host.new(@channel).compile_request(
172
+ path: nil,
173
+ source:,
174
+ importer:,
175
+ load_paths:,
176
+ syntax:,
177
+ url:,
178
+ charset:,
179
+ source_map:,
180
+ source_map_include_sources:,
181
+ style:,
182
+ functions:,
183
+ importers:,
184
+ alert_color:,
185
+ alert_ascii:,
186
+ fatal_deprecations:,
187
+ future_deprecations:,
188
+ logger:,
189
+ quiet_deps:,
190
+ silence_deprecations:,
191
+ verbose:
192
+ )
193
+ end
194
+
195
+ # @return [String] Information about the Sass implementation.
196
+ # @see https://sass-lang.com/documentation/js-api/variables/info/
197
+ def info
198
+ @info ||= [
199
+ ['sass-embedded', Embedded::VERSION, '(Embedded Host)', '[Ruby]'].join("\t"),
200
+ Host.new(@channel).version_request.join("\t")
201
+ ].join("\n").freeze
202
+ end
203
+
204
+ def close
205
+ @channel.close
206
+ end
207
+
208
+ def closed?
209
+ @channel.closed?
210
+ end
211
+ end
212
+ end
data/lib/sass/elf.rb ADDED
@@ -0,0 +1,222 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sass
4
+ # The {ELF} class.
5
+ #
6
+ # It parses ELF header to extract interpreter.
7
+ # @see https://github.com/torvalds/linux/blob/HEAD/include/uapi/linux/elf.h
8
+ # @see https://github.com/torvalds/linux/blob/HEAD/kernel/kexec_elf.c
9
+ class ELF
10
+ module PackInfo
11
+ PACK_MAP = {
12
+ Elf32_Ehdr: 'S<2L<5S<6',
13
+ Elf64_Ehdr: 'S<2L<Q<3L<S<6',
14
+ Elf32_Phdr: 'L<8',
15
+ Elf64_Phdr: 'L<2Q<6'
16
+ }.freeze
17
+
18
+ SIZE_MAP = {
19
+ Elf32_Ehdr: 36,
20
+ Elf64_Ehdr: 48,
21
+ Elf32_Phdr: 32,
22
+ Elf64_Phdr: 56
23
+ }.freeze
24
+
25
+ STRUCT_MAP = {
26
+ Elf32_Ehdr: %i[
27
+ e_type
28
+ e_machine
29
+ e_version
30
+ e_entry
31
+ e_phoff
32
+ e_shoff
33
+ e_flags
34
+ e_ehsize
35
+ e_phentsize
36
+ e_phnum
37
+ e_shentsize
38
+ e_shnum
39
+ e_shstrndx
40
+ ].freeze,
41
+ Elf64_Ehdr: %i[
42
+ e_type
43
+ e_machine
44
+ e_version
45
+ e_entry
46
+ e_phoff
47
+ e_shoff
48
+ e_flags
49
+ e_ehsize
50
+ e_phentsize
51
+ e_phnum
52
+ e_shentsize
53
+ e_shnum
54
+ e_shstrndx
55
+ ].freeze,
56
+ Elf32_Phdr: %i[
57
+ p_type
58
+ p_offset
59
+ p_vaddr
60
+ p_paddr
61
+ p_filesz
62
+ p_memsz
63
+ p_flags
64
+ p_align
65
+ ].freeze,
66
+ Elf64_Phdr: %i[
67
+ p_type
68
+ p_flags
69
+ p_offset
70
+ p_vaddr
71
+ p_paddr
72
+ p_filesz
73
+ p_memsz
74
+ p_align
75
+ ].freeze
76
+ }.freeze
77
+ end
78
+
79
+ private_constant :PackInfo
80
+
81
+ # These constants are for the segment types stored in the image headers
82
+ PT_NULL = 0
83
+ PT_LOAD = 1
84
+ PT_DYNAMIC = 2
85
+ PT_INTERP = 3
86
+ PT_NOTE = 4
87
+ PT_SHLIB = 5
88
+ PT_PHDR = 6
89
+ PT_TLS = 7
90
+ PT_LOOS = 0x60000000
91
+ PT_HIOS = 0x6fffffff
92
+ PT_LOPROC = 0x70000000
93
+ PT_HIPROC = 0x7fffffff
94
+
95
+ # These constants define the different elf file types
96
+ ET_NONE = 0
97
+ ET_REL = 1
98
+ ET_EXEC = 2
99
+ ET_DYN = 3
100
+ ET_CORE = 4
101
+ ET_LOPROC = 0xff00
102
+ ET_HIPROC = 0xffff
103
+
104
+ EI_NIDENT = 16
105
+
106
+ # e_ident[] indexes
107
+ EI_MAG0 = 0
108
+ EI_MAG1 = 1
109
+ EI_MAG2 = 2
110
+ EI_MAG3 = 3
111
+ EI_CLASS = 4
112
+ EI_DATA = 5
113
+ EI_VERSION = 6
114
+ EI_OSABI = 7
115
+ EI_PAD = 8
116
+
117
+ # EI_MAG
118
+ ELFMAG0 = 0x7f
119
+ ELFMAG1 = 0x45
120
+ ELFMAG2 = 0x4c
121
+ ELFMAG3 = 0x46
122
+ ELFMAG = [ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3].pack('C*')
123
+ SELFMAG = 4
124
+
125
+ # e_ident[EI_CLASS]
126
+ ELFCLASSNONE = 0
127
+ ELFCLASS32 = 1
128
+ ELFCLASS64 = 2
129
+ ELFCLASSNUM = 3
130
+
131
+ # e_ident[EI_DATA]
132
+ ELFDATANONE = 0
133
+ ELFDATA2LSB = 1
134
+ ELFDATA2MSB = 2
135
+
136
+ def initialize(buffer)
137
+ @buffer = buffer
138
+
139
+ @ehdr = { e_ident: @buffer.read(EI_NIDENT).unpack('C*') }
140
+ raise ArgumentError unless @ehdr[:e_ident].slice(EI_MAG0, SELFMAG).pack('C*') == ELFMAG
141
+
142
+ case @ehdr[:e_ident][EI_CLASS]
143
+ when ELFCLASS32
144
+ elf_ehdr = :Elf32_Ehdr
145
+ elf_phdr = :Elf32_Phdr
146
+ when ELFCLASS64
147
+ elf_ehdr = :Elf64_Ehdr
148
+ elf_phdr = :Elf64_Phdr
149
+ else
150
+ raise EncodingError
151
+ end
152
+
153
+ case @ehdr[:e_ident][EI_DATA]
154
+ when ELFDATA2LSB
155
+ little_endian = true
156
+ when ELFDATA2MSB
157
+ little_endian = false
158
+ else
159
+ raise EncodingError
160
+ end
161
+
162
+ @ehdr.merge!(read(elf_ehdr, little_endian))
163
+
164
+ @buffer.seek(@ehdr[:e_phoff], IO::SEEK_SET)
165
+ @proghdrs = Array.new(@ehdr[:e_phnum]) do
166
+ read(elf_phdr, little_endian)
167
+ end
168
+ end
169
+
170
+ def relocatable?
171
+ @ehdr[:e_type] == ET_REL
172
+ end
173
+
174
+ def executable?
175
+ @ehdr[:e_type] == ET_EXEC
176
+ end
177
+
178
+ def shared_object?
179
+ @ehdr[:e_type] == ET_DYN
180
+ end
181
+
182
+ def core?
183
+ @ehdr[:e_type] == ET_CORE
184
+ end
185
+
186
+ def interpreter
187
+ phdr = @proghdrs.find { |p| p[:p_type] == PT_INTERP }
188
+ return if phdr.nil?
189
+
190
+ @buffer.seek(phdr[:p_offset], IO::SEEK_SET)
191
+ interpreter = @buffer.read(phdr[:p_filesz])
192
+ raise EncodingError unless interpreter.end_with?("\0")
193
+
194
+ interpreter.chomp!("\0")
195
+ end
196
+
197
+ private
198
+
199
+ def read(type, little_endian)
200
+ size = PackInfo::SIZE_MAP[type]
201
+ format = little_endian ? PackInfo::PACK_MAP[type] : PackInfo::PACK_MAP[type].tr('<', '>')
202
+ [PackInfo::STRUCT_MAP[type], @buffer.read(size).unpack(format)].transpose.to_h
203
+ end
204
+
205
+ INTERPRETER = begin
206
+ proc_self_exe = '/proc/self/exe'
207
+ if File.exist?(proc_self_exe)
208
+ File.open(proc_self_exe, 'rb') do |file|
209
+ elf = ELF.new(file)
210
+ interpreter = elf.interpreter
211
+ if interpreter.nil? && elf.shared_object?
212
+ File.readlink(proc_self_exe)
213
+ else
214
+ interpreter
215
+ end
216
+ end
217
+ end
218
+ end.freeze
219
+ end
220
+
221
+ private_constant :ELF
222
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sass
4
- class Embedded
5
- VERSION = '1.6.2'
4
+ module Embedded
5
+ VERSION = '1.83.1'
6
6
  end
7
7
  end