File indexing completed on 2024-04-21 05:08:03

0001 # frozen_string_literal: true
0002 #
0003 # Copyright (C) 2015-2016 Harald Sitter <sitter@kde.org>
0004 #
0005 # This library is free software; you can redistribute it and/or
0006 # modify it under the terms of the GNU Lesser General Public
0007 # License as published by the Free Software Foundation; either
0008 # version 2.1 of the License, or (at your option) version 3, or any
0009 # later version accepted by the membership of KDE e.V. (or its
0010 # successor approved by the membership of KDE e.V.), which shall
0011 # act as a proxy defined in Section 6 of version 3 of the license.
0012 #
0013 # This library is distributed in the hope that it will be useful,
0014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
0015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016 # Lesser General Public License for more details.
0017 #
0018 # You should have received a copy of the GNU Lesser General Public
0019 # License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0020 
0021 require 'insensitive_hash/minimal'
0022 
0023 require_relative 'deb822'
0024 
0025 module Debian
0026   # Debian .changes parser
0027   class Changes < Deb822
0028     # FIXME: lazy read automatically when accessing fields
0029     attr_reader :fields
0030 
0031     File = Struct.new(:md5, :size, :section, :priority, :name)
0032     Checksum = Struct.new(:sum, :size, :file_name)
0033 
0034     # FIXME: pretty sure that should be in the base
0035     def initialize(file)
0036       @file = file
0037       @fields = InsensitiveHash.new
0038     end
0039 
0040     def parse!
0041       lines = ::File.new(@file).readlines
0042 
0043       # Source Paragraph
0044       fields = {
0045         mandatory: %w(format date source binary architecture version distribution maintainer description changes checksums-sha1 checksums-sha256 files),
0046         relationship: %w(),
0047         foldable: %w(binary) + %w(),
0048         multiline: %w(description changes checksums-sha1 checksums-sha256 files)
0049       }
0050       @fields = parse_paragraph(lines, fields)
0051 
0052       if @fields
0053         if @fields['files']
0054           # Mangle list fields into structs.
0055           @fields['files'] = parse_types(@fields['files'], File)
0056           %w(checksums-sha1 checksums-sha256).each do |key|
0057             @fields[key] = parse_types(@fields[key], Checksum)
0058           end
0059         end
0060       end
0061 
0062       # TODO: Strip custom fields and add a Control::flags_for(entry) method.
0063 
0064       # FIXME: signing verification not implemented
0065       #   this code works; needs to be somewhere generic
0066       #   also needs to rescue GPGME::Error::NoData
0067       #   in case the file is not signed
0068       # crypto = GPGME::Crypto.new
0069       # results = []
0070       # crypto.verify(data) do |signature|
0071       #   results << signature.valid?
0072       #
0073       # !results.empty? && results.all?
0074     end
0075 
0076     private
0077 
0078     def parse_types(lines, klass)
0079       lines.split($/).collect do |line|
0080         klass.new(*line.split(' '))
0081       end
0082     end
0083   end
0084 end