- make IniParser more strict (bug #306697)
[platform/upstream/libzypp.git] / zypp / parser / IniParser.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/parser/IniParser.cc
10  *
11 */
12 #include <iostream>
13 #include <sstream>
14
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/String.h"
17 #include "zypp/base/IOStream.h"
18 #include "zypp/base/UserRequestException.h"
19
20 #include "zypp/parser/ParseException.h"
21 #include "zypp/parser/IniParser.h"
22 #include "zypp/ProgressData.h"
23
24 using std::endl;
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
30 namespace parser
31 { /////////////////////////////////////////////////////////////////
32
33 ///////////////////////////////////////////////////////////////////
34 //
35 //      METHOD NAME : IniParser::IniParser
36 //      METHOD TYPE : Ctor
37 //
38 IniParser::IniParser()
39   : _line_nr(0)
40 {}
41
42 ///////////////////////////////////////////////////////////////////
43 //
44 //      METHOD NAME : IniParser::~IniParser
45 //      METHOD TYPE : Dtor
46 //
47 IniParser::~IniParser()
48 {}
49
50 void IniParser::beginParse()
51 {}
52
53 void IniParser::consume( const std::string &section, const std::string &key, const std::string &value )
54 {}
55
56 void IniParser::consume( const std::string &section )
57 {}
58
59 void IniParser::endParse()
60 {}
61
62 ///////////////////////////////////////////////////////////////////
63 //
64 //      METHOD NAME : IniParser::parse
65 //      METHOD TYPE : void
66 //
67 void IniParser::parse( const InputStream & input_r, const ProgressData::ReceiverFnc & progress )
68 {
69   MIL << "Start parsing " << input_r << endl;
70   _inputname = input_r.name();
71   beginParse();
72
73   ProgressData ticks( makeProgressData( input_r ) );
74   ticks.sendTo(progress);
75   ticks.toMin();
76
77   iostr::EachLine line( input_r );
78   for ( ; line; line.next() )
79   {
80     std::string trimmed = str::trim(*line);
81
82     if (trimmed.empty() || trimmed[0] == ';' || trimmed[0] == '#')
83       continue ; /* Comment lines */
84
85     if (trimmed[0] == '[')
86     {
87       std::string section = trimmed.substr(1, trimmed.find(']')-1);
88       consume(section);
89       section.swap(_current_section);
90       continue;
91     }
92
93     std::string::size_type pos = trimmed.find('=');
94
95     if (pos != std::string::npos)
96     {
97       std::string key = str::rtrim(trimmed.substr(0, pos));
98       if(key.find_first_of(" \t") != std::string::npos) {
99         std::string msg = str::form("%s: Key in line %d contains whitespace", _inputname.c_str(), line.lineNo());
100         ZYPP_THROW(ParseException(msg));
101       }
102       std::string value = str::ltrim(trimmed.substr(pos+1));
103       consume( _current_section, key, value);
104     }
105     else
106     {
107       std::string msg = str::form("%s: Line %d is missing '=' sign", _inputname.c_str(), line.lineNo());
108       ZYPP_THROW(ParseException(msg));
109     }
110
111     // set progress and allow cancel
112     if ( ! ticks.set( input_r.stream().tellg() ) )
113       ZYPP_THROW(AbortRequestException());
114   }
115   ticks.toMax();
116
117   endParse();
118   _inputname.clear();
119   MIL << "Done parsing " << input_r << endl;
120 }
121
122 /////////////////////////////////////////////////////////////////
123 } // namespace parser
124 ///////////////////////////////////////////////////////////////////
125 /////////////////////////////////////////////////////////////////
126 } // namespace zypp
127 ///////////////////////////////////////////////////////////////////