mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Bug #1924247: Possible to create recursive VL that crashes Calibre
The actual fix is in cache.py line 2218. Another change added the virtual fields to vl:x searches. The rest are improvements to error messages.
This commit is contained in:
parent
caca59de29
commit
a6f4b77cfd
@ -1086,17 +1086,18 @@ class Cache(object):
|
||||
return self._search_api(self, query, restriction, virtual_fields=virtual_fields, book_ids=book_ids)
|
||||
|
||||
@read_api
|
||||
def books_in_virtual_library(self, vl, search_restriction=None):
|
||||
def books_in_virtual_library(self, vl, search_restriction=None, virtual_fields=None):
|
||||
' Return the set of books in the specified virtual library '
|
||||
vl = self._pref('virtual_libraries', {}).get(vl) if vl else None
|
||||
if not vl and not search_restriction:
|
||||
return self.all_book_ids()
|
||||
# We utilize the search restriction cache to speed this up
|
||||
srch = partial(self._search, virtual_fields=virtual_fields)
|
||||
if vl:
|
||||
if search_restriction:
|
||||
return frozenset(self._search('', vl) & self._search('', search_restriction))
|
||||
return frozenset(self._search('', vl))
|
||||
return frozenset(self._search('', search_restriction))
|
||||
return frozenset(srch('', vl) & srch('', search_restriction))
|
||||
return frozenset(srch('', vl))
|
||||
return frozenset(srch('', search_restriction))
|
||||
|
||||
@read_api
|
||||
def number_of_books_in_virtual_library(self, vl=None, search_restriction=None):
|
||||
@ -2214,8 +2215,11 @@ class Cache(object):
|
||||
c = defaultdict(list)
|
||||
libraries = self._pref('virtual_libraries', {})
|
||||
for lib, expr in libraries.items():
|
||||
for book in self._search(expr, virtual_fields=virtual_fields):
|
||||
c[book].append(lib)
|
||||
try:
|
||||
for book in self._search(expr, virtual_fields=virtual_fields):
|
||||
c[book].append(lib)
|
||||
except Exception as e:
|
||||
c[book].append(_('[Error in virtual library {0}: {1}]').format(lib, str(e)))
|
||||
self.vls_for_books_cache = {b:tuple(sorted(libs, key=sort_key)) for b, libs in c.items()}
|
||||
if not book_ids:
|
||||
book_ids = self._all_book_ids()
|
||||
|
@ -513,7 +513,8 @@ class Parser(SearchQueryParser): # {{{
|
||||
if not vl:
|
||||
raise ParseException(_('No such Virtual library: {}').format(query))
|
||||
try:
|
||||
return candidates & self.dbcache.books_in_virtual_library(query)
|
||||
return candidates & self.dbcache.books_in_virtual_library(
|
||||
query, virtual_fields=self.virtual_fields)
|
||||
except RuntimeError:
|
||||
raise ParseException(_('Virtual library search is recursive: {}').format(query))
|
||||
|
||||
|
@ -312,7 +312,7 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
search_item_renamed = pyqtSignal()
|
||||
tag_item_renamed = pyqtSignal()
|
||||
refresh_required = pyqtSignal()
|
||||
restriction_error = pyqtSignal()
|
||||
restriction_error = pyqtSignal(object)
|
||||
drag_drop_finished = pyqtSignal(object)
|
||||
user_categories_edited = pyqtSignal(object, object)
|
||||
user_category_added = pyqtSignal()
|
||||
@ -1113,12 +1113,11 @@ class TagsModel(QAbstractItemModel): # {{{
|
||||
data = self.db.new_api.get_categories(sort=sort,
|
||||
book_ids=self.get_book_ids_to_use(),
|
||||
first_letter_sort=self.collapse_model == 'first letter')
|
||||
except:
|
||||
import traceback
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
data = self.db.new_api.get_categories(sort=sort,
|
||||
first_letter_sort=self.collapse_model == 'first letter')
|
||||
self.restriction_error.emit()
|
||||
self.restriction_error.emit(str(e))
|
||||
|
||||
if self.filter_categories_by:
|
||||
if self.filter_categories_by.startswith('='):
|
||||
|
@ -99,9 +99,10 @@ class TagBrowserMixin(object): # {{{
|
||||
def user_categories_edited(self):
|
||||
self.library_view.model().refresh()
|
||||
|
||||
def do_restriction_error(self):
|
||||
def do_restriction_error(self, e):
|
||||
error_dialog(self.tags_view, _('Invalid search restriction'),
|
||||
_('The current search restriction is invalid'), show=True)
|
||||
_('The current search restriction is invalid'),
|
||||
det_msg=str(e) if e else '', show=True)
|
||||
|
||||
def do_add_subcategory(self, on_category_key, new_category_name=None):
|
||||
'''
|
||||
|
@ -172,7 +172,7 @@ class TagsView(QTreeView): # {{{
|
||||
tag_item_renamed = pyqtSignal()
|
||||
search_item_renamed = pyqtSignal()
|
||||
drag_drop_finished = pyqtSignal(object)
|
||||
restriction_error = pyqtSignal()
|
||||
restriction_error = pyqtSignal(object)
|
||||
tag_item_delete = pyqtSignal(object, object, object, object, object)
|
||||
tag_identifier_delete = pyqtSignal(object, object)
|
||||
apply_tag_to_selected = pyqtSignal(object, object, object)
|
||||
|
Loading…
x
Reference in New Issue
Block a user