ocran 1.4.6 → 1.5.0

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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.txt +68 -0
  3. data/README.md +295 -10
  4. data/ext/extconf.rb +5 -1
  5. data/lib/ocran/aot_toolchain.rb +154 -0
  6. data/lib/ocran/command_output.rb +8 -1
  7. data/lib/ocran/compatibility_scan.rb +414 -0
  8. data/lib/ocran/cosmo_toolchain.rb +29 -7
  9. data/lib/ocran/dir_builder.rb +88 -38
  10. data/lib/ocran/direction.rb +190 -30
  11. data/lib/ocran/ed_resource.rb +113 -0
  12. data/lib/ocran/ed_resource_builder.rb +199 -0
  13. data/lib/ocran/file_path_set.rb +9 -5
  14. data/lib/ocran/gem_spec_queryable.rb +7 -3
  15. data/lib/ocran/host_config_helper.rb +11 -1
  16. data/lib/ocran/inno_setup_script_builder.rb +24 -14
  17. data/lib/ocran/launcher_batch_builder.rb +8 -11
  18. data/lib/ocran/npm_package.rb +106 -0
  19. data/lib/ocran/option.rb +425 -35
  20. data/lib/ocran/pe_imports.rb +96 -0
  21. data/lib/ocran/pe_resources.rb +226 -0
  22. data/lib/ocran/refine_pathname.rb +29 -32
  23. data/lib/ocran/roundhouse_builder.rb +316 -0
  24. data/lib/ocran/runner.rb +43 -11
  25. data/lib/ocran/runtime_sdk.rb +252 -0
  26. data/lib/ocran/spinel_builder.rb +183 -0
  27. data/lib/ocran/spinel_compatibility.rb +149 -0
  28. data/lib/ocran/static_runtime/boot.rb +443 -0
  29. data/lib/ocran/static_runtime/build_static_ext.rb +86 -0
  30. data/lib/ocran/static_runtime_builder.rb +814 -0
  31. data/lib/ocran/stub_builder.rb +70 -25
  32. data/lib/ocran/version.rb +1 -1
  33. data/lib/ocran/wasm_builder.rb +570 -0
  34. data/lib/ocran/wasm_compatibility.rb +198 -0
  35. data/lib/ocran/windows_command_escaping.rb +21 -0
  36. data/lib/ocran/zip_payload_builder.rb +18 -9
  37. data/lib/ocran/zip_writer.rb +48 -9
  38. data/src/Makefile +18 -2
  39. data/src/Makefile.mswin +65 -0
  40. data/src/inst_dir.c +34 -6
  41. data/src/path_utils.c +144 -0
  42. data/src/script_info.c +5 -0
  43. data/src/stub.c +77 -19
  44. data/src/stub.rc +1 -1
  45. data/src/system_utils.c +276 -155
  46. data/src/system_utils.h +46 -3
  47. data/src/system_utils_posix.c +243 -148
  48. data/src/unpack.c +9 -0
  49. metadata +22 -4
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require "fileutils"
2
3
  require "tempfile"
3
4
  require_relative "file_path_set"
4
5
 
@@ -119,7 +120,9 @@ module Ocran
119
120
  def initialize(path, chdir_before: nil, chdir_to_exe_dir: nil,
120
121
  debug_extract: nil, debug_mode: nil,
121
122
  enable_compression: nil, gui_mode: nil, icon_path: nil,
122
- run_in_exe_dir: nil, stub_path: nil)
123
+ run_in_exe_dir: nil, stub_path: nil,
124
+ version_strings: nil, file_version: nil, product_version: nil,
125
+ resource_strings: nil, execution_level: nil, application_manifest: nil)
123
126
  @dirs = FilePathSet.new
124
127
  @files = FilePathSet.new
125
128
  @data_size = 0
@@ -138,38 +141,65 @@ module Ocran
138
141
  else
139
142
  STUB_PATH
140
143
  end
141
- IO.copy_stream(stub_src, stub_tmp)
142
- stub = stub_tmp
144
+ begin
145
+ IO.copy_stream(stub_src, stub_tmp)
146
+ stub = stub_tmp
143
147
 
144
- # Clear any invalid security directory entries from the stub (Windows only)
145
- self.class.clear_invalid_security_entry(stub) if WINDOWS
148
+ # Clear any invalid security directory entries from the stub (Windows only)
149
+ self.class.clear_invalid_security_entry(stub) if WINDOWS
146
150
 
147
- # Embed icon resource (Windows only)
148
- if icon_path && WINDOWS
149
- require_relative "ed_icon"
150
- EdIcon.update_icon(stub, icon_path.to_s)
151
- end
151
+ # Embed icon resource (Windows only)
152
+ if icon_path && WINDOWS
153
+ require_relative "ed_icon"
154
+ EdIcon.update_icon(stub, icon_path.to_s)
155
+ end
152
156
 
153
- File.open(stub, "ab") do |of|
154
- @of = of
155
- @opcode_offset = @of.size
157
+ # Embed rcedit-style PE resources: version info, manifest, string table
158
+ # (Windows only). This must run before the opcode data is appended below,
159
+ # because BeginUpdateResource/EndUpdateResource rewrites the whole PE file.
160
+ # Only loaded when asked for, like ed_icon: it requires fiddle, which
161
+ # since Ruby 4.0 is a bundled gem that the application's own bundle
162
+ # (ocran run under its `bundle exec`) need not include.
163
+ resource_options = [version_strings, file_version, product_version,
164
+ resource_strings, execution_level, application_manifest]
165
+ if WINDOWS && resource_options.any? { |v| v && !(v.respond_to?(:empty?) && v.empty?) }
166
+ manifest_xml = application_manifest ? File.read(application_manifest, encoding: "UTF-8") : nil
167
+ require_relative "ed_resource"
168
+ EdResource.update(stub,
169
+ version_strings: version_strings,
170
+ file_version: file_version,
171
+ product_version: product_version,
172
+ resource_strings: resource_strings,
173
+ manifest_xml: manifest_xml,
174
+ execution_level: execution_level)
175
+ end
156
176
 
157
- write_header(debug_mode, debug_extract, chdir_before, enable_compression, run_in_exe_dir, chdir_to_exe_dir)
177
+ File.open(stub, "ab") do |of|
178
+ @of = of
179
+ @opcode_offset = @of.size
158
180
 
159
- b = proc {
160
- yield(self)
161
- }
181
+ write_header(debug_mode, debug_extract, chdir_before, enable_compression, run_in_exe_dir, chdir_to_exe_dir)
182
+
183
+ b = proc {
184
+ yield(self)
185
+ }
162
186
 
163
- if enable_compression && LZMA_CMD
164
- compress(&b)
165
- else
166
- b.yield
187
+ if enable_compression && LZMA_CMD
188
+ compress(&b)
189
+ else
190
+ b.yield
191
+ end
192
+
193
+ write_footer
167
194
  end
168
195
 
169
- write_footer
196
+ File.rename(stub, path)
197
+ rescue Exception
198
+ # The half-written executable sits next to the requested output,
199
+ # under a name nobody would look for; do not leave it behind.
200
+ FileUtils.rm_f(stub_tmp)
201
+ raise
170
202
  end
171
-
172
- File.rename(stub, path)
173
203
  File.chmod(0755, path) unless WINDOWS
174
204
  end
175
205
 
@@ -225,8 +255,23 @@ module Ocran
225
255
 
226
256
  IO.popen(LZMA_CMD, "r+b") do |lzma|
227
257
  _of, @of = @of, lzma
228
- Thread.new { yield(self); lzma.close_write }
258
+ writer = Thread.new do
259
+ # An error is re-raised in the main thread by writer.value below.
260
+ Thread.current.report_on_exception = false
261
+ yield(self)
262
+ ensure
263
+ # Always end the compressor's input, also when the block raised:
264
+ # otherwise copy_stream below waits for more output forever.
265
+ begin
266
+ lzma.close_write
267
+ rescue IOError, SystemCallError
268
+ # The pipe is already closed or broken; the compressor has
269
+ # nothing more to read either way.
270
+ end
271
+ end
229
272
  IO.copy_stream(lzma, _of)
273
+ writer.value
274
+ ensure
230
275
  @of = _of
231
276
  end
232
277
 
data/lib/ocran/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ocran
4
- VERSION = "1.4.6"
4
+ VERSION = "1.5.0"
5
5
  end