Skip to content

Commit

Permalink
Merge pull request #33 from libyui/match-ignoring-bidi
Browse files Browse the repository at this point in the history
rest-api: When finding table items by cell value, ignore BiDi control chars
  • Loading branch information
mvidner committed Jun 8, 2021
2 parents fff269e + 3030d7c commit 757c3f5
Show file tree
Hide file tree
Showing 21 changed files with 88 additions and 21 deletions.
2 changes: 1 addition & 1 deletion VERSION.cmake
@@ -1,6 +1,6 @@
SET( VERSION_MAJOR "4")
SET( VERSION_MINOR "2" )
SET( VERSION_PATCH "13" )
SET( VERSION_PATCH "14" )
SET( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}" )

SET( SONAME_MAJOR "15" )
Expand Down
1 change: 1 addition & 0 deletions libyui-rest-api/src/CMakeLists.txt
Expand Up @@ -45,6 +45,7 @@ set( SOURCES
YJsonSerializer.cc
YMenuWidgetActionHandler.cc
YTableActionHandler.cc
YWidgetActionHandler.cc
YWidgetFinder.cc
)

Expand Down
4 changes: 2 additions & 2 deletions libyui-rest-api/src/YDumbTabActionHandler.cc
Expand Up @@ -49,12 +49,12 @@ YDumbTabActionHandler::findItem( const std::string &item_label,
YItemConstIterator begin,
YItemConstIterator end ) const
{
std::string item_label_sanitized = boost::erase_all_copy(item_label, ShortcutChar);
std::string item_label_sanitized = normalize_label(item_label);
for ( YItemConstIterator it = begin; it != end; ++it )
{
YItem * item = *it;

if ( boost::erase_all_copy(item->label(), ShortcutChar) == item_label_sanitized )
if ( normalize_label(item->label()) == item_label_sanitized )
{
return item;
}
Expand Down
2 changes: 1 addition & 1 deletion libyui-rest-api/src/YMenuWidgetActionHandler.cc
Expand Up @@ -34,7 +34,7 @@ YMenuWidgetActionHandler::findItem( std::vector<std::string>::iterator path_begi
if ( !item )
return nullptr;

if ( boost::erase_all_copy( item->label(), ShortcutChar ) == *path_begin )
if ( normalize_label( item->label() ) == *path_begin )
{
if ( std::next( path_begin ) == path_end )
{
Expand Down
2 changes: 1 addition & 1 deletion libyui-rest-api/src/YMenuWidgetActionHandler.h
Expand Up @@ -30,7 +30,7 @@ class YMenuWidgetActionHandler : public YWidgetActionHandler
template<typename T>
std::function<void (T*)> get_handler( T *widget, const std::string &value ) {
return [&] ( T *menu_selector ) {
std::string value_sanitized = boost::erase_all_copy( value, ShortcutChar );
std::string value_sanitized = normalize_label( value );
// Vector of string to store path to the tree item
std::vector<std::string> path;
boost::split( path, value_sanitized, boost::is_any_of( TreePathDelimiter ) );
Expand Down
2 changes: 1 addition & 1 deletion libyui-rest-api/src/YTableActionHandler.cc
Expand Up @@ -90,7 +90,7 @@ YTableActionHandler::table_findItem( std::vector<std::string>::const_iterator pa
if ( ! item )
return nullptr;

if ( item->label(column_id) == *path_begin )
if ( normalize_label ( item->label(column_id) ) == *path_begin )
{
if ( std::next( path_begin ) == path_end )
return item;
Expand Down
49 changes: 49 additions & 0 deletions libyui-rest-api/src/YWidgetActionHandler.cc
@@ -0,0 +1,49 @@
/*
Copyright (C) 2021 SUSE LLC
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) version 3.0 of the License. This library
is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details. You should have received a copy of the GNU
Lesser General Public License along with this library; if not, write
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Floor, Boston, MA 02110-1301 USA
*/

#include <codecvt>
#include <boost/range/algorithm/remove_if.hpp>

#include "YWidgetActionHandler.h"

static
std::string normalize_label_bidi(const std::string& label)
{
static std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;

static wchar_t bidi_controls[] { L'\u202a', L'\u202b', L'\u202c', L'\u202d', L'\u202e', L'\u2066', L'\u2067', L'\u2068', L'\u2069' };

std::wstring wlabel(conv.from_bytes(label));
auto new_end = boost::remove_if(wlabel, boost::is_any_of(bidi_controls));
// for s == "hello",
// remove_if(s, is_consonant) leaves s == "eollo" and returns new_end
// pointing at the first 'l', so an additional erase is needed:
wlabel.erase(new_end, wlabel.end());
std::string cleaned(conv.to_bytes(wlabel));

return cleaned;
}

static
std::string normalize_label_shortcut(const std::string& label)
{
return boost::erase_all_copy(label, ShortcutChar);
}

std::string YWidgetActionHandler::normalize_label(const std::string & label)
{
return normalize_label_shortcut(normalize_label_bidi(label));
}
13 changes: 13 additions & 0 deletions libyui-rest-api/src/YWidgetActionHandler.h
Expand Up @@ -111,6 +111,19 @@ class YWidgetActionHandler
}
};
}

// Normalize a label before comparing it for equality:
// - remove shortcut characters (&)
// - remove BiDi control characters (added to certain table cells to render pathnames correctly)
static std::string normalize_label(const std::string & label);

// Apply normalize_label to both arguments and compare the result with ==.
static bool normalized_labels_equal(const std::string & a, const std::string & b)
{
std::string na = normalize_label(a);
std::string nb = normalize_label(b);
return na == nb;
}
};

#endif //YWidgetActionHandler_h
5 changes: 2 additions & 3 deletions libyui-rest-api/src/YWidgetFinder.cc
Expand Up @@ -23,6 +23,7 @@
#include <yui/YWidgetID.h>

#include "YWidgetFinder.h"
#include "YWidgetActionHandler.h"


// internal helper methods
Expand Down Expand Up @@ -94,14 +95,12 @@ void find_widgets(YWidget *w, WidgetArray &array, std::function<bool (YWidget*)>

static bool filter_by_label_rec(YWidget *w, const std::string &label)
{
std::string label_sanitized = boost::erase_all_copy( label, ShortcutChar );
// check the widget label if it is defined
if ( w->propertySet().contains("Label") )
{
std::string widget_label = w->getProperty("Label").stringVal();
boost::erase_all( widget_label, ShortcutChar );

if ( widget_label == label_sanitized )
if ( YWidgetActionHandler::normalized_labels_equal( widget_label, label ) )
return true;
}
return false;
Expand Down
2 changes: 0 additions & 2 deletions libyui-rest-api/src/YWidgetFinder.h
Expand Up @@ -20,8 +20,6 @@
#include <string>
#include <vector>

#define ShortcutChar "&"

class YWidget;

typedef std::vector<YWidget*> WidgetArray;
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-bindings.spec
Expand Up @@ -20,7 +20,7 @@
Name: libyui-bindings

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0
Summary: Bindings for libyui
License: LGPL-2.1-only OR LGPL-3.0-only
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-ncurses-pkg.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui-ncurses-pkg

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-ncurses-rest-api.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui-ncurses-rest-api

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-ncurses.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui-ncurses

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-qt-graph.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui-qt-graph

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-qt-pkg.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui-qt-pkg

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-qt-rest-api.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui-qt-rest-api

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-qt.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui-qt

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down
2 changes: 1 addition & 1 deletion package/libyui-rest-api.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui-rest-api

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down
7 changes: 7 additions & 0 deletions package/libyui.changes
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Fri Jun 4 08:27:03 UTC 2021 - Martin Vidner <mvidner@suse.com>

- rest-api: When finding table items by cell value,
ignore BiDi control chars (bsc#1128091)
- 4.2.14

-------------------------------------------------------------------
Wed Jun 2 11:18:42 UTC 2021 - Stefan Hundhammer <shundhammer@suse.com>

Expand Down
2 changes: 1 addition & 1 deletion package/libyui.spec
Expand Up @@ -19,7 +19,7 @@
Name: libyui

# DO NOT manually bump the version here; instead, use rake version:bump
Version: 4.2.13
Version: 4.2.14
Release: 0

%define so_version 15
Expand Down

0 comments on commit 757c3f5

Please sign in to comment.