sass-embedded 1.83.4 → 1.85.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2779af1e4b4b8994dc7cb041657aeb55af947f387fd30a6f9e41407c0166f8d0
4
- data.tar.gz: fe9fa40596a2465ed7eabbe17e62bc42e882474fb34d37999214ca4606fb545a
3
+ metadata.gz: 8d69723752e7561b2169d77e6337afed2a140b7defcaf69678a09f6894f51cc1
4
+ data.tar.gz: 0bb6712d55b4b27c039759259d3c73bfdda135da91287a94abd5f808ae35f522
5
5
  SHA512:
6
- metadata.gz: dcc32242410a35d3ab99fde179f1cd0e2da3b37526dd1e038113bd675ce2bf16904e8e207719f0faef78b40de8592af9e34a1663a209828b3814629c3bf93420
7
- data.tar.gz: 57d324ae11da9cb8a5057fbc7cccc1a75aabb85cd3c37ff4bf9ff6bc0e4c76aeef7ea882da92b79f625098024d41efe0168ef1549efb20b830aeb5f205226fe3
6
+ metadata.gz: 81b180b87b1b3d85830abfaf63c32622fb233a47b9194eab1c92cdd7d1bcd64b88fa4df88a2aad22a39545f336e8ff90fc5e7643b67c77a374c87c91dcb2bfc7
7
+ data.tar.gz: 91c1113d71107b89a5a4909b4b91629dc28ee8d1f26cc78523e32f67914d8190ff09e4c5e55c61c009a9f2a3c011d4808b9c34b7f993219657313d489b944d04
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,6 @@
1
1
  {
2
2
  "dependencies": {
3
- "sass": "1.83.4"
4
- }
3
+ "sass": "1.85.0"
4
+ },
5
+ "packageManager": "npm@11.0.0+sha512.11dff29565d2297c74e7c594a9762581bde969f0aa5cbe6f5b3644bf008a16c065ece61094d9ffbb81125be38df8e1ba43eb8244b3d30c61eb797e9a2440e3ec"
5
6
  }
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.0'
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.0
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-14 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.0
128
+ source_code_uri: https://github.com/sass-contrib/sass-embedded-host-ruby/tree/v1.85.0
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.3
146
146
  specification_version: 4
147
147
  summary: Use dart-sass with Ruby!
148
148
  test_files: []