Welcome to mirror list, hosted at ThFree Co, Russian Federation.

create_symbol_files_service.rb « symbols « nuget « packages « services « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 03e14ba00e1657c48c14f28122532845c8d46d4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# frozen_string_literal: true

module Packages
  module Nuget
    module Symbols
      class CreateSymbolFilesService
        ExtractionError = Class.new(StandardError)
        SYMBOL_ENTRIES_LIMIT = 100
        CONTENT_TYPE = 'application/octet-stream'

        def initialize(package, package_zip_file)
          @package = package
          @symbol_entries = package_zip_file.glob('**/*.pdb')
        end

        def execute
          return if symbol_entries.empty?

          process_symbol_entries
        rescue ExtractionError => e
          Gitlab::ErrorTracking.log_exception(e, class: self.class.name, package_id: package.id)
        end

        private

        attr_reader :package, :symbol_entries

        def process_symbol_entries
          Tempfile.create('nuget_extraction_symbol_file') do |tmp_file|
            symbol_entries.each_with_index do |entry, index|
              raise ExtractionError, 'too many symbol entries' if index >= SYMBOL_ENTRIES_LIMIT

              entry.extract(tmp_file.path) { true }
              File.open(tmp_file.path) do |file|
                create_symbol(entry.name, file)
              end
            end
          end
        rescue Zip::EntrySizeError => e
          raise ExtractionError, "symbol file has the wrong entry size: #{e.message}"
        rescue Zip::EntryNameError => e
          raise ExtractionError, "symbol file has the wrong entry name: #{e.message}"
        end

        def create_symbol(path, file)
          signature = extract_signature(file.read(1.kilobyte))
          return if signature.blank?

          ::Packages::Nuget::Symbol.create!(
            package: package,
            file: { tempfile: file, filename: path.downcase, content_type: CONTENT_TYPE },
            file_path: path,
            signature: signature,
            size: file.size
          )
        rescue StandardError => e
          Gitlab::ErrorTracking.log_exception(e, class: self.class.name, package_id: package.id)
        end

        def extract_signature(content_fragment)
          ExtractSymbolSignatureService
            .new(content_fragment)
            .execute
            .payload
        end
      end
    end
  end
end