SET(LIBZYPP_MAJOR "14")
SET(LIBZYPP_COMPATMINOR "30")
SET(LIBZYPP_MINOR "32")
-SET(LIBZYPP_PATCH "1")
+SET(LIBZYPP_PATCH "2")
#
-# LAST RELEASED: 14.32.1 (30)
+# LAST RELEASED: 14.32.2 (30)
# (The number in parenthesis is LIBZYPP_COMPATMINOR)
#=======
ADD_CUSTOM_COMMAND(
OUTPUT ${TRANSLATION_SET_CONTENT}
COMMAND tar xfj ${CMAKE_CURRENT_SOURCE_DIR}/${TRANSLATION_SET}
+ COMMAND sed -i '/^msgid/s/do not forbid installation of %s/remove lock to allow installation of %s/' *.po
+ COMMAND sed -i '/^msgid/s/do not keep %s installed/remove lock to allow removal of %s/' *.po
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${TRANSLATION_SET}
)
-------------------------------------------------------------------
+Wed Dec 17 18:44:26 CET 2014 - ma@suse.de
+
+- Improve conflict message for locked packages (bnc#828631)
+- Fix broken de-escaping in str::splitEscaped (bnc#909772)
+- cleanup loging
+- version 14.32.2 (30)
+
+-------------------------------------------------------------------
Fri Dec 12 14:00:01 CET 2014 - ma@suse.de
- CheckAccessDeleted: Filter PIDs running in a container (bnc#909143)
string s( "simple non-escaped string" );
vector<string> v;
- insert_iterator<vector<string> > ii (v,v.end());
- splitEscaped( s, ii );
+ splitEscaped( s, std::back_inserter(v) );
BOOST_CHECK_EQUAL( v.size(), 3 );
+ BOOST_CHECK_EQUAL( v[0], "simple" );
+ BOOST_CHECK_EQUAL( v[1], "non-escaped" );
+ BOOST_CHECK_EQUAL( v[2], "string" );
v.clear();
s = string( "\"escaped sentence \"" );
- ii = insert_iterator<vector<string> >( v, v.end() );
- splitEscaped( s, ii );
+ splitEscaped( s, std::back_inserter(v) );
BOOST_CHECK_EQUAL( v.size(), 1 );
- BOOST_CHECK_EQUAL( v.front(), string( "escaped sentence " ) );
+ BOOST_CHECK_EQUAL( v[0], "escaped sentence " );
v.clear();
s = string( "\"escaped \\\\sent\\\"ence \\\\\"" );
- ii = insert_iterator<vector<string> >( v, v.end() );
- splitEscaped( s, ii );
+ splitEscaped( s, std::back_inserter(v) );
BOOST_CHECK_EQUAL( v.size(), 1 );
- BOOST_CHECK_EQUAL( v.front(), string( "escaped \\sent\"ence \\" ) );
-
+ BOOST_CHECK_EQUAL( v[0], "escaped \\sent\"ence \\" );
v.clear();
s = string( "escaped sentence\\ with\\ space" );
- ii = insert_iterator<vector<string> >( v, v.end() );
- splitEscaped( s, ii );
+ splitEscaped( s, std::back_inserter(v) );
BOOST_CHECK_EQUAL( v.size(), 2 );
- BOOST_CHECK_EQUAL( v[1], string( "sentence with space" ) );
+ BOOST_CHECK_EQUAL( v[0], "escaped" );
+ BOOST_CHECK_EQUAL( v[1], "sentence with space" );
// split - join
v.clear();
s = "some line \"\" foo\\ a foo\\\\ b";
str::splitEscaped( s, std::back_inserter(v) );
+ BOOST_CHECK_EQUAL( v.size(), 6 );
+ BOOST_CHECK_EQUAL( v[0], "some" );
+ BOOST_CHECK_EQUAL( v[1], "line" );
+ BOOST_CHECK_EQUAL( v[2], "" );
+ BOOST_CHECK_EQUAL( v[3], "foo a" );
+ BOOST_CHECK_EQUAL( v[4], "foo\\" );
+ BOOST_CHECK_EQUAL( v[5], "b" );
BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end() ) );
// split - join using alternate sepchar
s = str::joinEscaped( v.begin(), v.end(), 'o' );
v.clear();
str::splitEscaped( s, std::back_inserter(v), "o" );
+ BOOST_CHECK_EQUAL( v.size(), 6 );
+ BOOST_CHECK_EQUAL( v[0], "some" );
+ BOOST_CHECK_EQUAL( v[1], "line" );
+ BOOST_CHECK_EQUAL( v[2], "" );
+ BOOST_CHECK_EQUAL( v[3], "foo a" );
+ BOOST_CHECK_EQUAL( v[4], "foo\\" );
+ BOOST_CHECK_EQUAL( v[5], "b" );
BOOST_CHECK_EQUAL( s, str::joinEscaped( v.begin(), v.end(), 'o' ) );
}
+BOOST_AUTO_TEST_CASE(bnc_909772)
+{
+ // While \-escaping processes single-quote, double-quote, backslash and sepchar[ ]
+ // deescaping failed to process the quotes correctly.
+ std::string s;
+ std::vector<std::string> v;
+
+ v.clear();
+ v.push_back("");
+ v.push_back("'\" \\");
+ v.push_back("\\'\\\"\\ \\\\");
+ s = str::joinEscaped( v.begin(), v.end() );
+ BOOST_CHECK_EQUAL( s, "\"\"" " " "\\'\\\"\\ \\\\" " " "\\\\\\'\\\\\\\"\\\\\\ \\\\\\\\" );
+
+ s += " ";
+ s += "'" "\\\\\" \\ \\\\" "'\\ single"; // single quote: all literal, no ' inside
+
+ s += " ";
+ s += "\"" "\\'\\\" \\ \\\\" "\"\\ double";// double quote: all literal except \\ \"
+
+ v.clear();
+ splitEscaped( s, std::back_inserter(v) );
+ BOOST_CHECK_EQUAL( v.size(), 5 );
+ BOOST_CHECK_EQUAL( v[0], "" );
+ BOOST_CHECK_EQUAL( v[1], "'\" \\" );
+ BOOST_CHECK_EQUAL( v[2], "\\'\\\"\\ \\\\" );
+ BOOST_CHECK_EQUAL( v[3], "\\\\\" \\ \\\\ single" );
+ BOOST_CHECK_EQUAL( v[4], "\\'\" \\ \\ double" );
+}
+
BOOST_AUTO_TEST_CASE(testsplitEscapedWithEmpty)
{
string s( "simple:non-escaped:string" );
/** Split \a line_r into words with respect to escape delimeters.
* Any sequence of characters in \a sepchars_r is treated as
- * delimiter if not inside "" or "" or escaped by \, but not \\.
+ * delimiter if not inside \c "" or \c '' or escaped by \c \.
+ *
+ * \li A non-quoted backslash (\) preserves the literal value of the next character.
+ * \li Enclosing characters in single quotes preserves the literal value of each
+ * character within the quotes. A single quote may not occur between single
+ * quotes, even when preceded by a backslash.
+ * \li Enclosing characters in double quotes preserves the literal value of all
+ * characters within the quotes, with the exception of \c \. The backslash
+ * retains its special meaning only when followed by \c " or \c \.
+ *
* The words are passed to OutputIterator \a result_r.
*
* \see \ref splitEscaped
* \code
* example splitted strings
* normal line -> 2 elements ( "normal", "line" )
- * escaped\ line -> 1 element( "escaped line" )
+ * escaped\ line -> 1 element(escaped line)
* "quoted line" -> 1 element same as above
* 'quoted line' -> 1 element same as above
- * "escaped quote\'" -> 1 element ( "escaped quote'" )
+ * "escaped quote\"" -> 1 element (escaped quote")
*
* \param line_r The string to parse.
* \param result_r
}
// after the leading sepchars
+ enum class Quote { None, Slash, Single, Double, DoubleSlash };
+ std::vector<char> buf;
+ Quote quoting = Quote::None;
for ( beg = cur; *beg; beg = cur, ++result_r, ++ret )
- {
- if ( *cur == '"' || *cur == '\'' )
- {
- char closeChar = *cur;
- ++cur;
- bool cont = true;
- while (cont)
- {
- while ( *cur && *cur != closeChar)
- ++cur;
- if ( *cur == '\0' )
- {
- return ret; //TODO parsing exception no closing quote
- }
- int escCount = 0;
- const char * esc = cur-1;
- while ( esc != beg && *esc == '\\' )
- {
- escCount++;
- --esc;
- }
- cont = (escCount % 2 == 1); // find some non escaped escape char
- cur++; //skip quote
- }
-
- std::string s( beg+1, cur-beg-2 ); //without quotes
- //transform escaped escape
- replaceAll( s, "\\\\", "\\" );
- //transform escaped quotes (only same as open
- char tmpn[2] = { closeChar, 0 };
- char tmpo[3] = { '\\', closeChar, 0 };
- replaceAll( s, tmpo, tmpn );
-
- *result_r = s;
- }
- else
- {
- // skip non sepchars
- while( *cur && !::strchr( sepchars_r, *cur ) )
- {
- //ignore char after backslash
- if ( *cur == '\\' )
- {
- ++cur;
- }
- ++cur;
- }
- // build string
- std::string s( beg, cur-beg );
- //transform escaped escape
- replaceAll( s, "\\\\", "\\" );
+ {
+ // read next value until unquoted sepchar
+ buf.clear();
+ quoting = Quote::None;
+ do {
+ switch ( quoting )
+ {
+ case Quote::None:
+ switch ( *cur )
+ {
+ case '\\': quoting = Quote::Slash; break;
+ case '\'': quoting = Quote::Single; break;
+ case '"': quoting = Quote::Double; break;
+ default: buf.push_back( *cur ); break;
+ }
+ break;
+
+ case Quote::Slash:
+ buf.push_back( *cur );
+ quoting = Quote::None;
+ break;
+
+ case Quote::Single:
+ switch ( *cur )
+ {
+ case '\'': quoting = Quote::None; break;
+ default: buf.push_back( *cur ); break;
+ }
+ break;
+
+ case Quote::Double:
+ switch ( *cur )
+ {
+ case '\"': quoting = Quote::None; break;
+ case '\\': quoting = Quote::DoubleSlash; break;
+ default: buf.push_back( *cur ); break;
+ }
+ break;
+
+ case Quote::DoubleSlash:
+ switch ( *cur )
+ {
+ case '\"': /*fallthrough*/
+ case '\\': buf.push_back( *cur ); break;
+ default:
+ buf.push_back( '\\' );
+ buf.push_back( *cur );
+ break;
+ }
+ quoting = Quote::Double;
+ break;
+ }
+ ++cur;
+ } while ( *cur && ( quoting != Quote::None || !::strchr( sepchars_r, *cur ) ) );
+ *result_r = std::string( buf.begin(), buf.end() );
- const char *delimeter = sepchars_r;
- while ( *delimeter )
- {
- std::string ds("\\");
- const char tmp[2] = { *delimeter, '\0' };
- std::string del(tmp);
- ds+= del;
- replaceAll( s, ds, del );
- ++delimeter;
- }
- *result_r = s;
- }
- // skip sepchars
- if ( *cur && ::strchr( sepchars_r, *cur ) )
- ++cur;
- while ( *cur && ::strchr( sepchars_r, *cur ) )
- {
- ++cur;
- if (withEmpty)
- {
- *result_r = "";
- ++ret;
- }
- }
- // the last was a separator => one more field
- if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
- {
- *result_r = "";
- ++ret;
- }
- }
+ // skip sepchars
+ if ( *cur && ::strchr( sepchars_r, *cur ) )
+ ++cur;
+ while ( *cur && ::strchr( sepchars_r, *cur ) )
+ {
+ ++cur;
+ if (withEmpty)
+ {
+ *result_r = "";
+ ++ret;
+ }
+ }
+ // the last was a separator => one more field
+ if ( !*cur && withEmpty && ::strchr( sepchars_r, *(cur-1) ) )
+ {
+ *result_r = "";
+ ++ret;
+ }
+ }
return ret;
}
ERR << "Unknown attribute in [" << *its << "]: " << it->first << "=" << it->second << " ignored" << endl;
}
- USR << dict.baseurls( *its ) << endl;
for ( auto & url : dict.baseurls( *its ) )
{
if ( ! proxy.empty() && url.getQueryParam( "proxy" ).empty() )
if (poolItem) {
if (pool->installed && s.get()->repo == pool->installed) {
problemSolution->addSingleAction (poolItem, REMOVE);
- string description = str::form (_("do not keep %s installed"), s.asString().c_str() );
+ string description = str::form (_("remove lock to allow removal of %s"), s.asString().c_str() );
MIL << description << endl;
problemSolution->addDescription (description);
} else {
problemSolution->addDescription (description);
} else {
problemSolution->addSingleAction (poolItem, UNLOCK);
- string description = str::form (_("do not forbid installation of %s"), itemToString( poolItem ).c_str());
+ string description = str::form (_("remove lock to allow installation of %s"), itemToString( poolItem ).c_str());
MIL << description << endl;
problemSolution->addDescription (description);
}