diff --git a/agent-ini/src/IniParser.cc b/agent-ini/src/IniParser.cc index e68f091ad..6ea002f09 100644 --- a/agent-ini/src/IniParser.cc +++ b/agent-ini/src/IniParser.cc @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "IniParser.h" #include "IniFile.h" @@ -1015,9 +1017,33 @@ int IniParser::write() inifile.clean (); return bugs ? -1 : 0; } + +/** sprintf to a std::string, throwing runtime_error on OOM */ +std::string format (const char * format, ...) { + // copied from y2util/stringutil.h but added the throw + // since we don't want to silently corrupt config files + char * buf = 0; + std::string val; + + va_list ap; + va_start( ap, format ); + + int numprinted = vasprintf(&buf, format, ap); + if (numprinted >= 0) { + val = buf; + free( buf ); + } + else { + throw std::runtime_error("vasprintf failed in ag_ini. Out of memory?"); + } + + va_end( ap ); + return val; +} + int IniParser::write_helper(IniSection&ini, ofstream&of, int depth) { - char * out_buffer; + string out_buffer; string indent; string indent2; int readby = ini.getReadBy (); @@ -1033,9 +1059,8 @@ int IniParser::write_helper(IniSection&ini, ofstream&of, int depth) of << ini.getComment(); if (readby>=0 && readby < (int)sections.size ()) { - asprintf (&out_buffer, sections[readby].begin.out.c_str (), ini.getName()); + out_buffer = format (sections[readby].begin.out.c_str (), ini.getName()); of << indent << out_buffer << "\n"; - free (out_buffer); } IniIterator @@ -1056,9 +1081,8 @@ int IniParser::write_helper(IniSection&ini, ofstream&of, int depth) of << e.getComment(); if (e.getReadBy()>=0 && e.getReadBy() < (int)params.size ()) { // bnc#492859, a fixed buffer is too small - asprintf (&out_buffer, params[e.getReadBy ()].line.out.c_str (), e.getName(), e.getValue()); + out_buffer = format (params[e.getReadBy ()].line.out.c_str (), e.getName(), e.getValue()); of << indent2 << out_buffer << "\n"; - free(out_buffer); } e.clean(); } @@ -1068,9 +1092,8 @@ int IniParser::write_helper(IniSection&ini, ofstream&of, int depth) of << indent << ini.getEndComment(); if (readby>=0 && readby < (int) sections.size () && sections[readby].end_valid) { - asprintf (&out_buffer, sections[readby].end.out.c_str (), ini.getName()); + out_buffer = format (sections[readby].end.out.c_str (), ini.getName()); of << indent << out_buffer << "\n"; - free(out_buffer); } ini.clean(); return 0; diff --git a/package/yast2-core.changes b/package/yast2-core.changes index eb813fee3..5db077154 100644 --- a/package/yast2-core.changes +++ b/package/yast2-core.changes @@ -3,6 +3,7 @@ Wed May 23 15:35:00 CEST 2012 - mvidner@suse.cz - agent-ini: do not truncate strings longer than 2048 while writing (bnc#492859, bnc#763386) +- agent-ini: if we cannot format a string, fail loudly (bnc#763386#c10) - 2.17.35.4 -------------------------------------------------------------------