sass-embedded 1.83.4 → 1.85.1

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: 2779af1e4b4b8994dc7cb041657aeb55af947f387fd30a6f9e41407c0166f8d0
4
- data.tar.gz: fe9fa40596a2465ed7eabbe17e62bc42e882474fb34d37999214ca4606fb545a
3
+ metadata.gz: 53d0f1a6a02fe07581f2497fd69e21216a3a1e8bfd7d23643bd274595df73b41
4
+ data.tar.gz: 4b7687eb3bafd4cc21d5e473b3d6681c0f89b9aef84b457a09f6cafe6cfdd37c
5
5
  SHA512:
6
- metadata.gz: dcc32242410a35d3ab99fde179f1cd0e2da3b37526dd1e038113bd675ce2bf16904e8e207719f0faef78b40de8592af9e34a1663a209828b3814629c3bf93420
7
- data.tar.gz: 57d324ae11da9cb8a5057fbc7cccc1a75aabb85cd3c37ff4bf9ff6bc0e4c76aeef7ea882da92b79f625098024d41efe0168ef1549efb20b830aeb5f205226fe3
6
+ metadata.gz: 2e89874966d20a22859c41b946ea32d0591fa2f4d5292c393d0ad515eec1e8d29d9153c6bde2411db78ab939d1d27ed50c579aa325bf80ae5f10eed7ff8924b2
7
+ data.tar.gz: c7e8ba0b9346c455c659c64305677da630004ee6337e3ab69c07a2804c690422a0d943a63000875c42b4e0a3705963e64424bd50193ca29ff7e5305b85fc7b26
data/ext/sass/Rakefile CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  require 'rake/clean'
4
4
 
5
+ require_relative '../../lib/sass/elf'
6
+
7
+ ELF = Sass.const_get(:ELF)
8
+
5
9
  task default: %i[install clean]
6
10
 
7
11
  task install: %w[cli.rb] do
@@ -11,6 +15,7 @@ end
11
15
  CLEAN.include %w[
12
16
  protoc.exe
13
17
  ruby
18
+ true
14
19
  *.proto
15
20
  *.tar.gz
16
21
  *.zip
@@ -70,8 +75,6 @@ rescue NotImplementedError
70
75
  end
71
76
 
72
77
  file 'cli.rb' => %w[dart-sass] do |t|
73
- require_relative '../../lib/sass/elf'
74
-
75
78
  begin
76
79
  exe = 'dart-sass/sass'
77
80
  exe = "#{exe}#{['', '.bat', '.exe'].find { |ext| File.exist?("#{exe}#{ext}") }}"
@@ -89,7 +92,7 @@ file 'cli.rb' => %w[dart-sass] do |t|
89
92
  end
90
93
 
91
94
  interpreter = File.open(command[0], 'rb') do |file|
92
- Sass.const_get(:ELF).new(file).interpreter
95
+ ELF.new(file).interpreter
93
96
  rescue ArgumentError
94
97
  nil
95
98
  end
@@ -158,6 +161,128 @@ rule '_pb.rb' => %w[.proto protoc.exe] do |t|
158
161
  sh './protoc.exe', '--proto_path=.', '--ruby_out=.', t.source
159
162
  end
160
163
 
164
+ file 'true' do |t|
165
+ case Platform::CPU
166
+ when 'aarch64'
167
+ ei_class = ELF::ELFCLASS64
168
+ ei_data = ELF::ELFDATA2LSB
169
+ e_machine = 0xb7
170
+ e_flags = 0
171
+
172
+ # 0000000000400078 <PT_LOAD#0>:
173
+ # 400078: d2800ba8 mov x8, #0x5d // =93
174
+ # 40007c: d2800000 mov x0, #0x0 // =0
175
+ # 400080: d4000001 svc #0
176
+ entry_point = [0xd2800ba8, 0xd2800000, 0xd4000001].pack('L<3')
177
+ when 'arm'
178
+ ei_class = ELF::ELFCLASS32
179
+ ei_data = ELF::ELFDATA2LSB
180
+ e_machine = 0x28
181
+ e_flags = 0x5000400
182
+
183
+ # 00400054 <PT_LOAD#0>:
184
+ # 400054: 2701 movs r7, #0x1
185
+ # 400056: 2000 movs r0, #0x0
186
+ # 400058: df00 svc #0x0
187
+ entry_point = [0x2701, 0x2000, 0xdf00].pack('S<3')
188
+ when 'riscv64'
189
+ ei_class = ELF::ELFCLASS64
190
+ ei_data = ELF::ELFDATA2LSB
191
+ e_machine = 0xf3
192
+ e_flags = 0x5
193
+
194
+ # 0000000000400078 <PT_LOAD#0>:
195
+ # 400078: 05d00893 li a7, 0x5d
196
+ # 40007c: 4501 li a0, 0x0
197
+ # 40007e: 00000073 ecall
198
+ entry_point = [0x05d00893, 0x4501, 0x00000073].pack('L<S<L<')
199
+ when 'x86_64'
200
+ ei_class = ELF::ELFCLASS64
201
+ ei_data = ELF::ELFDATA2LSB
202
+ e_machine = 0x3e
203
+ e_flags = 0
204
+
205
+ # 0000000000400078 <PT_LOAD#0>:
206
+ # 400078: 31 ff xorl %edi, %edi
207
+ # 40007a: b8 3c 00 00 00 movl $0x3c, %eax
208
+ # 40007f: 0f 05 syscall
209
+ entry_point = %w[31ffb83c0000000f05].pack('H*')
210
+ when 'i386'
211
+ ei_class = ELF::ELFCLASS32
212
+ ei_data = ELF::ELFDATA2LSB
213
+ e_machine = 0x03
214
+ e_flags = 0
215
+
216
+ # 00400054 <PT_LOAD#0>:
217
+ # 400054: 31 db xorl %ebx, %ebx
218
+ # 400056: b8 01 00 00 00 movl $0x1, %eax
219
+ # 40005b: cd 80 int $0x80
220
+ entry_point = %w[31dbb801000000cd80].pack('H*')
221
+ else
222
+ raise NotImplementedError
223
+ end
224
+
225
+ case ei_class
226
+ when ELF::ELFCLASS32
227
+ e_ehsize = ELF::Elf32_Ehdr.sizeof
228
+ e_phentsize = ELF::Elf32_Phdr.sizeof
229
+ e_shentsize = ELF::Elf32_Shdr.sizeof
230
+ when ELF::ELFCLASS64
231
+ e_ehsize = ELF::Elf64_Ehdr.sizeof
232
+ e_phentsize = ELF::Elf64_Phdr.sizeof
233
+ e_shentsize = ELF::Elf64_Shdr.sizeof
234
+ else
235
+ raise EncodingError
236
+ end
237
+
238
+ e_phoff = e_ehsize
239
+
240
+ p_offset = e_phoff + e_phentsize
241
+ p_vaddr = (2**22) + p_offset
242
+ p_filesz = entry_point.length
243
+ p_memsz = p_filesz
244
+
245
+ e_entry = p_vaddr
246
+ e_entry += 1 if Platform::CPU == 'arm'
247
+
248
+ ELF.allocate.instance_eval do
249
+ @ehdr = {
250
+ e_ident: [127, 69, 76, 70, ei_class, ei_data, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
251
+ e_type: ELF::ET_EXEC,
252
+ e_machine:,
253
+ e_version: 1,
254
+ e_entry:,
255
+ e_phoff:,
256
+ e_shoff: 0,
257
+ e_flags:,
258
+ e_ehsize:,
259
+ e_phentsize:,
260
+ e_phnum: 1,
261
+ e_shentsize:,
262
+ e_shnum: 0,
263
+ e_shstrndx: 0
264
+ }
265
+ @phdrs = [
266
+ {
267
+ p_type: ELF::PT_LOAD,
268
+ p_flags: ELF::PF_R | ELF::PF_X,
269
+ p_offset:,
270
+ p_vaddr:,
271
+ p_paddr: 0,
272
+ p_filesz:,
273
+ p_memsz:,
274
+ p_align: 4096
275
+ }
276
+ ]
277
+ @shdrs = []
278
+
279
+ File.open(t.name, 'wb', 0o755) do |file|
280
+ dump(file)
281
+ file.write(entry_point)
282
+ end
283
+ end
284
+ end
285
+
161
286
  # This is a FileUtils extension that defines several additional commands to be
162
287
  # added to the FileUtils utility functions.
163
288
  module FileUtils
@@ -302,46 +427,140 @@ module FileUtils
302
427
  end
303
428
  end
304
429
 
305
- # The {SassConfig} module.
306
- module SassConfig
307
- module Platform
308
- OS = case RbConfig::CONFIG['host_os'].downcase
309
- when /darwin/
310
- 'darwin'
311
- when /linux-android/
312
- 'linux-android'
313
- when /linux-musl/
314
- 'linux-musl'
315
- when /linux-uclibc/
316
- 'linux-uclibc'
317
- when /linux/
318
- 'linux'
319
- when *Gem::WIN_PATTERNS
320
- 'windows'
321
- else
322
- RbConfig::CONFIG['host_os'].downcase
323
- end
430
+ # The {Platform} module.
431
+ module Platform
432
+ # @see https://docs.freebsd.org/en/articles/linux-emulation/
433
+ # @see https://docs.freebsd.org/en/books/handbook/linuxemu/
434
+ module Linuxulator
435
+ module_function
324
436
 
325
- CPU = case RbConfig::CONFIG['host_cpu'].downcase
326
- when /amd64|x86_64|x64/
327
- 'x86_64'
328
- when /i\d86|x86|i86pc/
329
- 'x86'
330
- when /arm64|aarch64/
331
- 'aarch64'
332
- when /arm/
333
- 'arm'
334
- when /ppc64le|powerpc64le/
335
- 'powerpc64le'
336
- else
337
- RbConfig::CONFIG['host_cpu']
338
- end
437
+ def enabled?
438
+ return false unless RbConfig::CONFIG['host_os'].include?('freebsd')
439
+
440
+ return true if defined?(Platform::OS) && Platform::OS.include?('linux')
441
+
442
+ begin
443
+ Rake::Task['true'].invoke unless File.exist?('true')
444
+ rescue NotImplementedError
445
+ # do nothing
446
+ end
339
447
 
340
- ARCH = "#{CPU}-#{OS}".freeze
448
+ system('./true') == true
449
+ end
450
+
451
+ def host_os(root = compat_linux_emul_path)
452
+ return 'linux-none' unless File.symlink?(File.absolute_path('proc/self/exe', root))
453
+
454
+ if (Platform::CPU == 'aarch64' &&
455
+ File.exist?(File.absolute_path('lib/ld-linux-aarch64.so.1', root))) ||
456
+ (Platform::CPU == 'riscv64' &&
457
+ File.exist?(File.absolute_path('lib/ld-linux-riscv64-lp64d.so.1', root))) ||
458
+ (Platform::CPU == 'x86_64' &&
459
+ File.exist?(File.absolute_path('lib64/ld-linux-x86-64.so.2', root))) ||
460
+ (Platform::CPU == 'i386' &&
461
+ File.exist?(File.absolute_path('lib/ld-linux.so.2', root)))
462
+ return 'linux-gnu'
463
+ end
464
+
465
+ if Platform::CPU == 'arm' &&
466
+ File.exist?(File.absolute_path('lib/ld-linux-armhf.so.3', root))
467
+ return 'linux-gnueabihf'
468
+ end
469
+
470
+ if %w[aarch64 riscv64 x86_64 i386].include?(Platform::CPU) &&
471
+ File.exist?(File.absolute_path("lib/ld-musl-#{Platform::CPU}.so.1", root))
472
+ return 'linux-musl'
473
+ end
474
+
475
+ if Platform::CPU == 'arm' &&
476
+ File.exist?(File.absolute_path('lib/ld-musl-armhf.so.1', root))
477
+ return 'linux-musleabihf'
478
+ end
479
+
480
+ if (%w[aarch64 riscv64 x86_64].include?(Platform::CPU) &&
481
+ File.exist?(File.absolute_path('system/bin/linker64', root))) ||
482
+ (Platform::CPU == 'i386' &&
483
+ File.exist?(File.absolute_path('system/bin/linker', root)))
484
+ return 'linux-android'
485
+ end
486
+
487
+ if Platform::CPU == 'arm' &&
488
+ File.exist?(File.absolute_path('system/bin/linker', root))
489
+ return 'linux-androideabi'
490
+ end
491
+
492
+ 'linux-none'
493
+ end
494
+
495
+ def compat_linux_emul_path
496
+ require 'fiddle'
497
+
498
+ lib = Fiddle.dlopen(nil)
499
+ sysctlbyname = Fiddle::Function.new(
500
+ lib['sysctlbyname'],
501
+ [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_SIZE_T],
502
+ Fiddle::TYPE_INT
503
+ )
504
+
505
+ name = Fiddle::Pointer.to_ptr('compat.linux.emul_path')
506
+ oldp = Fiddle::NULL
507
+ oldlenp = Fiddle::Pointer.malloc(Fiddle::SIZEOF_SIZE_T, Fiddle::RUBY_FREE)
508
+ newp = Fiddle::NULL
509
+ newlen = 0
510
+ raise SystemCallError.new(nil, Fiddle.last_error) if sysctlbyname.call(name, oldp, oldlenp, newp, newlen) == -1
511
+
512
+ oldp = Fiddle::Pointer.malloc(oldlenp.ptr.to_i, Fiddle::RUBY_FREE)
513
+ raise SystemCallError.new(nil, Fiddle.last_error) if sysctlbyname.call(name, oldp, oldlenp, newp, newlen) == -1
514
+
515
+ oldp.to_s
516
+ rescue SystemCallError
517
+ nil
518
+ end
341
519
  end
342
520
 
343
- private_constant :Platform
521
+ HOST_CPU = RbConfig::CONFIG['host_cpu'].downcase
522
+
523
+ CPU = case HOST_CPU
524
+ when /amd64|x86_64|x64/
525
+ 'x86_64'
526
+ when /i\d86|x86|i86pc/
527
+ 'i386'
528
+ when /arm64|aarch64/
529
+ 'aarch64'
530
+ when /arm/
531
+ 'arm'
532
+ when /ppc64le|powerpc64le/
533
+ 'ppc64le'
534
+ else
535
+ HOST_CPU
536
+ end
537
+
538
+ HOST_OS = (Linuxulator.enabled? ? Linuxulator.host_os : RbConfig::CONFIG['host_os']).downcase
539
+
540
+ OS = case HOST_OS
541
+ when /darwin/
542
+ 'darwin'
543
+ when /linux-android/
544
+ 'linux-android'
545
+ when /linux-musl/
546
+ 'linux-musl'
547
+ when /linux-none/
548
+ 'linux-none'
549
+ when /linux-uclibc/
550
+ 'linux-uclibc'
551
+ when /linux/
552
+ 'linux'
553
+ when *Gem::WIN_PATTERNS
554
+ 'windows'
555
+ else
556
+ HOST_OS
557
+ end
558
+
559
+ ARCH = "#{CPU}-#{OS}".freeze
560
+ end
344
561
 
562
+ # The {SassConfig} module.
563
+ module SassConfig
345
564
  module_function
346
565
 
347
566
  def package_json(path = '.')
@@ -380,7 +599,7 @@ module SassConfig
380
599
  end
381
600
 
382
601
  cpu = case Platform::CPU
383
- when 'x86'
602
+ when 'i386'
384
603
  'ia32'
385
604
  when 'x86_64'
386
605
  'x64'
@@ -415,7 +634,7 @@ module SassConfig
415
634
  os = case Platform::OS
416
635
  when 'darwin'
417
636
  'osx'
418
- when 'linux', 'linux-android', 'linux-musl', 'linux-uclibc'
637
+ when 'linux', 'linux-android', 'linux-musl', 'linux-none', 'linux-uclibc'
419
638
  'linux'
420
639
  when 'windows'
421
640
  'windows'
@@ -424,13 +643,13 @@ module SassConfig
424
643
  end
425
644
 
426
645
  cpu = case Platform::CPU
427
- when 'x86'
646
+ when 'i386'
428
647
  'x86_32'
429
648
  when 'x86_64'
430
649
  'x86_64'
431
650
  when 'aarch64'
432
651
  'aarch_64'
433
- when 'powerpc64le'
652
+ when 'ppc64le'
434
653
  'ppcle_64'
435
654
  when 's390x'
436
655
  's390_64'
@@ -492,7 +711,7 @@ module SassConfig
492
711
  end
493
712
 
494
713
  def gem_platform
495
- platform = Gem::Platform.new("#{Platform::CPU}-#{RbConfig::CONFIG['host_os']}")
714
+ platform = Gem::Platform.new("#{Platform::CPU}-#{Platform::HOST_OS}")
496
715
  case Platform::OS
497
716
  when 'darwin'
498
717
  case platform.cpu
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "dependencies": {
3
- "sass": "1.83.4"
3
+ "sass": "1.85.1"
4
4
  }
5
5
  }
data/lib/sass/elf.rb CHANGED
@@ -7,73 +7,30 @@ module Sass
7
7
  # @see https://github.com/torvalds/linux/blob/HEAD/include/uapi/linux/elf.h
8
8
  # @see https://github.com/torvalds/linux/blob/HEAD/kernel/kexec_elf.c
9
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
10
+ # The {PackInfo} class.
11
+ class PackInfo
12
+ def initialize(format:, sizeof:, struct:)
13
+ @format_le = format.freeze
14
+ @format_be = format.tr('<', '>').freeze
15
+ @sizeof = sizeof.freeze
16
+ @struct = struct.freeze
17
+ end
18
+
19
+ attr_reader :sizeof
20
+
21
+ def pack(io, data, little_endian)
22
+ raise ArgumentError if io.write(data.values_at(*@struct).pack(format(little_endian))) != @sizeof
23
+ end
24
+
25
+ def unpack(io, little_endian)
26
+ @struct.zip(io.read(@sizeof).unpack(format(little_endian))).to_h
27
+ end
28
+
29
+ private
30
+
31
+ def format(little_endian)
32
+ little_endian ? @format_le : @format_be
33
+ end
77
34
  end
78
35
 
79
36
  private_constant :PackInfo
@@ -92,6 +49,8 @@ module Sass
92
49
  PT_LOPROC = 0x70000000
93
50
  PT_HIPROC = 0x7fffffff
94
51
 
52
+ PN_XNUM = 0xffff
53
+
95
54
  # These constants define the different elf file types
96
55
  ET_NONE = 0
97
56
  ET_REL = 1
@@ -103,6 +62,154 @@ module Sass
103
62
 
104
63
  EI_NIDENT = 16
105
64
 
65
+ Elf32_Ehdr = PackInfo.new(
66
+ format: "a#{EI_NIDENT}S<2L<5S<6",
67
+ sizeof: 52,
68
+ struct: %i[
69
+ e_ident
70
+ e_type
71
+ e_machine
72
+ e_version
73
+ e_entry
74
+ e_phoff
75
+ e_shoff
76
+ e_flags
77
+ e_ehsize
78
+ e_phentsize
79
+ e_phnum
80
+ e_shentsize
81
+ e_shnum
82
+ e_shstrndx
83
+ ]
84
+ ).freeze
85
+
86
+ Elf64_Ehdr = PackInfo.new(
87
+ format: "a#{EI_NIDENT}S<2L<Q<3L<S<6",
88
+ sizeof: 64,
89
+ struct: %i[
90
+ e_ident
91
+ e_type
92
+ e_machine
93
+ e_version
94
+ e_entry
95
+ e_phoff
96
+ e_shoff
97
+ e_flags
98
+ e_ehsize
99
+ e_phentsize
100
+ e_phnum
101
+ e_shentsize
102
+ e_shnum
103
+ e_shstrndx
104
+ ]
105
+ ).freeze
106
+
107
+ # These constants define the permissions on sections in the program header, p_flags.
108
+ PF_R = 0x4
109
+ PF_W = 0x2
110
+ PF_X = 0x1
111
+
112
+ Elf32_Phdr = PackInfo.new(
113
+ format: 'L<8',
114
+ sizeof: 32,
115
+ struct: %i[
116
+ p_type
117
+ p_offset
118
+ p_vaddr
119
+ p_paddr
120
+ p_filesz
121
+ p_memsz
122
+ p_flags
123
+ p_align
124
+ ]
125
+ ).freeze
126
+
127
+ Elf64_Phdr = PackInfo.new(
128
+ format: 'L<2Q<6',
129
+ sizeof: 56,
130
+ struct: %i[
131
+ p_type
132
+ p_flags
133
+ p_offset
134
+ p_vaddr
135
+ p_paddr
136
+ p_filesz
137
+ p_memsz
138
+ p_align
139
+ ]
140
+ ).freeze
141
+
142
+ # sh_type
143
+ SHT_NULL = 0
144
+ SHT_PROGBITS = 1
145
+ SHT_SYMTAB = 2
146
+ SHT_STRTAB = 3
147
+ SHT_RELA = 4
148
+ SHT_HASH = 5
149
+ SHT_DYNAMIC = 6
150
+ SHT_NOTE = 7
151
+ SHT_NOBITS = 8
152
+ SHT_REL = 9
153
+ SHT_SHLIB = 10
154
+ SHT_DYNSYM = 11
155
+ SHT_NUM = 12
156
+ SHT_LOPROC = 0x70000000
157
+ SHT_HIPROC = 0x7fffffff
158
+ SHT_LOUSER = 0x80000000
159
+ SHT_HIUSER = 0xffffffff
160
+
161
+ # sh_flags
162
+ SHF_WRITE = 0x1
163
+ SHF_ALLOC = 0x2
164
+ SHF_EXECINSTR = 0x4
165
+ SHF_RELA_LIVEPATCH = 0x00100000
166
+ SHF_RO_AFTER_INIT = 0x00200000
167
+ SHF_MASKPROC = 0xf0000000
168
+
169
+ # special section indexes
170
+ SHN_UNDEF = 0
171
+ SHN_LORESERVE = 0xff00
172
+ SHN_LOPROC = 0xff00
173
+ SHN_HIPROC = 0xff1f
174
+ SHN_LIVEPATCH = 0xff20
175
+ SHN_ABS = 0xfff1
176
+ SHN_COMMON = 0xfff2
177
+ SHN_HIRESERVE = 0xffff
178
+
179
+ Elf32_Shdr = PackInfo.new(
180
+ format: 'L<10',
181
+ sizeof: 40,
182
+ struct: %i[
183
+ sh_name
184
+ sh_type
185
+ sh_flags
186
+ sh_addr
187
+ sh_offset
188
+ sh_size
189
+ sh_link
190
+ sh_info
191
+ sh_addralign
192
+ sh_entsize
193
+ ]
194
+ ).freeze
195
+
196
+ Elf64_Shdr = PackInfo.new(
197
+ format: 'L<2Q<4L<2Q<2',
198
+ sizeof: 64,
199
+ struct: %i[
200
+ sh_name
201
+ sh_type
202
+ sh_flags
203
+ sh_addr
204
+ sh_offset
205
+ sh_size
206
+ sh_link
207
+ sh_info
208
+ sh_addralign
209
+ sh_entsize
210
+ ]
211
+ ).freeze
212
+
106
213
  # e_ident[] indexes
107
214
  EI_MAG0 = 0
108
215
  EI_MAG1 = 1
@@ -133,24 +240,84 @@ module Sass
133
240
  ELFDATA2LSB = 1
134
241
  ELFDATA2MSB = 2
135
242
 
136
- def initialize(buffer)
137
- @buffer = buffer
243
+ def initialize(io, program_headers: true, section_headers: false)
244
+ io.rewind
245
+ e_ident = io.read(EI_NIDENT).unpack('C*')
246
+ raise ArgumentError unless e_ident.slice(EI_MAG0, SELFMAG).pack('C*') == ELFMAG
247
+
248
+ case e_ident[EI_CLASS]
249
+ when ELFCLASS32
250
+ elf_ehdr = Elf32_Ehdr
251
+ elf_phdr = Elf32_Phdr
252
+ elf_shdr = Elf32_Shdr
253
+ when ELFCLASS64
254
+ elf_ehdr = Elf64_Ehdr
255
+ elf_phdr = Elf64_Phdr
256
+ elf_shdr = Elf64_Shdr
257
+ else
258
+ raise EncodingError
259
+ end
260
+
261
+ case e_ident[EI_DATA]
262
+ when ELFDATA2LSB
263
+ little_endian = true
264
+ when ELFDATA2MSB
265
+ little_endian = false
266
+ else
267
+ raise EncodingError
268
+ end
269
+
270
+ io.rewind
271
+ ehdr = elf_ehdr.unpack(io, little_endian)
272
+ ehdr[:e_ident] = e_ident
138
273
 
139
- @ehdr = { e_ident: @buffer.read(EI_NIDENT).unpack('C*') }
140
- raise ArgumentError unless @ehdr[:e_ident].slice(EI_MAG0, SELFMAG).pack('C*') == ELFMAG
274
+ phdrs = if program_headers && ehdr[:e_phnum].positive?
275
+ io.seek(ehdr[:e_phoff], IO::SEEK_SET)
276
+ Array.new(ehdr[:e_phnum]) do
277
+ elf_phdr.unpack(io, little_endian)
278
+ end
279
+ else
280
+ []
281
+ end
141
282
 
142
- case @ehdr[:e_ident][EI_CLASS]
283
+ shdrs = if section_headers && ehdr[:e_shnum].positive?
284
+ io.seek(ehdr[:e_shoff], IO::SEEK_SET)
285
+ Array.new(ehdr[:e_shnum]) do
286
+ elf_shdr.unpack(io, little_endian)
287
+ end
288
+ else
289
+ []
290
+ end
291
+
292
+ @io = io
293
+ @ehdr = ehdr
294
+ @phdrs = phdrs
295
+ @shdrs = shdrs
296
+ end
297
+
298
+ def dump(io)
299
+ e_ident = @ehdr[:e_ident]
300
+ raise ArgumentError unless e_ident.slice(EI_MAG0, SELFMAG).pack('C*') == ELFMAG
301
+
302
+ ehdr = @ehdr.dup
303
+ ehdr[:e_ident] = e_ident.pack('C*')
304
+ phdrs = @phdrs
305
+ shdrs = @shdrs
306
+
307
+ case e_ident[EI_CLASS]
143
308
  when ELFCLASS32
144
- elf_ehdr = :Elf32_Ehdr
145
- elf_phdr = :Elf32_Phdr
309
+ elf_ehdr = Elf32_Ehdr
310
+ elf_phdr = Elf32_Phdr
311
+ elf_shdr = Elf32_Shdr
146
312
  when ELFCLASS64
147
- elf_ehdr = :Elf64_Ehdr
148
- elf_phdr = :Elf64_Phdr
313
+ elf_ehdr = Elf64_Ehdr
314
+ elf_phdr = Elf64_Phdr
315
+ elf_shdr = Elf64_Shdr
149
316
  else
150
317
  raise EncodingError
151
318
  end
152
319
 
153
- case @ehdr[:e_ident][EI_DATA]
320
+ case e_ident[EI_DATA]
154
321
  when ELFDATA2LSB
155
322
  little_endian = true
156
323
  when ELFDATA2MSB
@@ -159,12 +326,20 @@ module Sass
159
326
  raise EncodingError
160
327
  end
161
328
 
162
- @ehdr.merge!(read(elf_ehdr, little_endian))
329
+ io.rewind
330
+ elf_ehdr.pack(io, ehdr, little_endian)
163
331
 
164
- @buffer.seek(@ehdr[:e_phoff], IO::SEEK_SET)
165
- @proghdrs = Array.new(@ehdr[:e_phnum]) do
166
- read(elf_phdr, little_endian)
332
+ io.seek(ehdr[:e_phoff], IO::SEEK_SET) if ehdr[:e_phnum].positive?
333
+ phdrs.each do |phdr|
334
+ elf_phdr.pack(io, phdr, little_endian)
167
335
  end
336
+
337
+ io.seek(ehdr[:e_shoff], IO::SEEK_SET) if ehdr[:e_shnum].positive?
338
+ shdrs.each do |shdr|
339
+ elf_shdr.pack(io, shdr, little_endian)
340
+ end
341
+
342
+ io.flush
168
343
  end
169
344
 
170
345
  def relocatable?
@@ -184,24 +359,16 @@ module Sass
184
359
  end
185
360
 
186
361
  def interpreter
187
- phdr = @proghdrs.find { |p| p[:p_type] == PT_INTERP }
362
+ phdr = @phdrs.find { |p| p[:p_type] == PT_INTERP }
188
363
  return if phdr.nil?
189
364
 
190
- @buffer.seek(phdr[:p_offset], IO::SEEK_SET)
191
- interpreter = @buffer.read(phdr[:p_filesz])
365
+ @io.seek(phdr[:p_offset], IO::SEEK_SET)
366
+ interpreter = @io.read(phdr[:p_filesz])
192
367
  raise EncodingError unless interpreter.end_with?("\0")
193
368
 
194
369
  interpreter.chomp!("\0")
195
370
  end
196
371
 
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
372
  INTERPRETER = begin
206
373
  proc_self_exe = '/proc/self/exe'
207
374
  if File.exist?(proc_self_exe)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sass
4
4
  module Embedded
5
- VERSION = '1.83.4'
5
+ VERSION = '1.85.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sass-embedded
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.83.4
4
+ version: 1.85.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - なつき
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-01-14 00:00:00.000000000 Z
10
+ date: 2025-02-25 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake
@@ -124,8 +124,8 @@ licenses:
124
124
  - MIT
125
125
  metadata:
126
126
  bug_tracker_uri: https://github.com/sass-contrib/sass-embedded-host-ruby/issues
127
- documentation_uri: https://rubydoc.info/gems/sass-embedded/1.83.4
128
- source_code_uri: https://github.com/sass-contrib/sass-embedded-host-ruby/tree/v1.83.4
127
+ documentation_uri: https://rubydoc.info/gems/sass-embedded/1.85.1
128
+ source_code_uri: https://github.com/sass-contrib/sass-embedded-host-ruby/tree/v1.85.1
129
129
  funding_uri: https://github.com/sponsors/ntkme
130
130
  rubygems_mfa_required: 'true'
131
131
  rdoc_options: []
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
142
  - !ruby/object:Gem::Version
143
143
  version: '0'
144
144
  requirements: []
145
- rubygems_version: 3.6.2
145
+ rubygems_version: 3.6.5
146
146
  specification_version: 4
147
147
  summary: Use dart-sass with Ruby!
148
148
  test_files: []