libzypp  12.16.5
CheckSum.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #include <iostream>
13 #include <sstream>
14 
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/Gettext.h"
17 #include "zypp/base/String.h"
18 
19 #include "zypp/CheckSum.h"
20 #include "zypp/Digest.h"
21 
22 using std::endl;
23 
25 namespace zypp
26 {
27 
28  const std::string & CheckSum::md5Type()
29  { static std::string _type( "md5" ); return _type; }
30 
31  const std::string & CheckSum::shaType()
32  { static std::string _type( "sha" ); return _type; }
33 
34  const std::string & CheckSum::sha1Type()
35  { static std::string _type( "sha1" ); return _type; }
36 
37  const std::string & CheckSum::sha256Type()
38  { static std::string _type( "sha256" ); return _type; }
39 
40 
42  {}
43 
44  CheckSum::CheckSum( const std::string & checksum )
45  {
46  *this = CheckSum( std::string(), checksum );
47  }
48 
49  CheckSum::CheckSum( const std::string & type, const std::string & checksum )
50  : _type( str::toLower( type ) )
51  , _checksum( checksum )
52  {
53  switch ( checksum.size() )
54  {
55  case 64:
56  if ( _type == sha256Type() )
57  return;
58  if ( _type.empty() || _type == shaType() )
59  {
60  _type = sha256Type();
61  return;
62  }
63  // else: dubious
64  break;
65 
66  case 40:
67  if ( _type == sha1Type() )
68  return;
69  if ( _type.empty() || _type == shaType() )
70  {
71  _type = sha1Type();
72  return;
73  }
74  // else: dubious
75  break;
76 
77  case 32:
78  if ( _type == md5Type() )
79  return;
80  if ( _type.empty() )
81  {
82  _type = md5Type();
83  return;
84  }
85  // else: dubious
86  break;
87 
88  case 0:
89  return; // empty checksum is ok
90  break;
91 
92  default:
93  if ( _type.empty() )
94  {
95  WAR << "Can't determine type of " << checksum.size() << " byte checksum '" << _checksum << "'" << endl;
96  return;
97  }
98  // else: dubious
99  break;
100  }
101 
102  // dubious: Throw on malformed known types, otherwise log a warning.
103  std::string msg = str::form ( _("Dubious type '%s' for %u byte checksum '%s'"),
104  _type.c_str(), checksum.size(), _checksum.c_str() );
105  if ( _type == md5Type()
106  || _type == shaType()
107  || _type == sha1Type()
108  || _type == sha256Type() )
109  {
110  ZYPP_THROW( CheckSumException( msg ) );
111  }
112  else
113  {
114  WAR << msg << endl;
115  }
116  }
117 
118  CheckSum::CheckSum( const std::string & type_r, std::istream & input_r )
119  {
120  if ( input_r.good() && ! type_r.empty() )
121  {
122  _type = str::toLower( type_r );
123  _checksum = Digest::digest( _type, input_r );
124  if ( ! input_r.eof() || _checksum.empty() )
125  {
126  _type = _checksum = std::string();
127  }
128  }
129  }
130 
131  std::string CheckSum::type() const
132  { return _type; }
133 
134  std::string CheckSum::checksum() const
135  { return _checksum; }
136 
137  bool CheckSum::empty() const
138  { return (checksum().empty() || type().empty()); }
139 
140  std::string CheckSum::asString() const
141  {
142  std::ostringstream str;
143  str << *this;
144  return str.str();
145  }
146 
147  std::ostream & operator<<( std::ostream & str, const CheckSum & obj )
148  {
149  if ( obj.checksum().empty() )
150  {
151  return str << std::string("NoCheckSum");
152  }
153 
154  return str << ( obj.type().empty() ? std::string("UNKNOWN") : obj.type() ) << '-' << obj.checksum();
155  }
156 
158  bool operator==( const CheckSum & lhs, const CheckSum & rhs )
159  { return lhs.checksum() == rhs.checksum() && lhs.type() == rhs.type(); }
160 
162  bool operator!=( const CheckSum & lhs, const CheckSum & rhs )
163  { return ! ( lhs == rhs ); }
164 
166 } // namespace zypp