Repository: LMFDB/lmfdb

Issue:
Dirichlet character search by label error message
If I search by label for 3329.z from the Dirichlet characters homepage http://lmfdb.xyz/Character/Dirichlet/ the error message is "Error: the value z is invalid. It should be a positive integer coprime to and no greater than the modulus 3329." this should be changed in the case to reflect the fact that searching by orbit label is fine, just that z is too far down the alphabet.


Discussion:

Resolving patch:
diff --git a/lmfdb/characters/main.py b/lmfdb/characters/main.py
--- a/lmfdb/characters/main.py
+++ b/lmfdb/characters/main.py
@@ -264,7 +264,11 @@ def render_Dirichletwebpage(modulus=None, number=None):
 
     number = label_to_number(modulus, number)
     if number == 0:
-        flash_error("the value %s is invalid. It should be a positive integer coprime to and no greater than the modulus %s.", args['number'], args['modulus'])
+        flash_error(
+            "the value %s is invalid. It should either be a positive integer "
+            "coprime to and no greater than the modulus %s, or a letter that "
+            "corresponds to a valid orbit index.", args['number'], args['modulus']
+        )
         return redirect(url_for(".render_Dirichletwebpage"))
     args['number'] = number
     webchar = make_webchar(args)
diff --git a/lmfdb/galois_groups/transitive_group.py b/lmfdb/galois_groups/transitive_group.py
--- a/lmfdb/galois_groups/transitive_group.py
+++ b/lmfdb/galois_groups/transitive_group.py
@@ -473,7 +473,7 @@ def resolve_display(resolves):
         if j[0] != old_deg:
             if old_deg < 0:
                 ans += '<table><tr><th>'
-                ans += '|G/N|<th>Galois groups for stem field(s)'
+                ans += '|G/N|<th>Galois groups for <a title = "stem field(s)" knowl="nf.stem_field">stem field(s)</a>'
             else:
                 ans += '</td></tr>'
             old_deg = j[0]
diff --git a/lmfdb/utils/search_parsing.py b/lmfdb/utils/search_parsing.py
--- a/lmfdb/utils/search_parsing.py
+++ b/lmfdb/utils/search_parsing.py
@@ -29,7 +29,7 @@
 
 
 class SearchParser(object):
-    def __init__(self, f, clean_info, prep_ranges, prep_plus, pass_name, default_field, default_name, default_qfield):
+    def __init__(self, f, clean_info, prep_ranges, prep_plus, pass_name, default_field, default_name, default_qfield,error_is_safe):
         self.f = f
         self.clean_info = clean_info
         self.prep_ranges = prep_ranges
@@ -38,6 +38,7 @@ def __init__(self, f, clean_info, prep_ranges, prep_plus, pass_name, default_fie
         self.default_field = default_field
         self.default_name = default_name
         self.default_qfield = default_qfield
+        self.error_is_safe = error_is_safe # Indicates that the message in raised exception contains no user input, so it is not escaped
     def __call__(self, info, query, field=None, name=None, qfield=None, *args, **kwds):
         try:
             if field is None: field=self.default_field
@@ -68,14 +69,17 @@ def __call__(self, info, query, field=None, name=None, qfield=None, *args, **kwd
             if self.clean_info:
                 info[field] = inp
         except (ValueError, AttributeError, TypeError) as err:
-            flash_error("<span style='color:black'>%s</span> is not a valid input for <span style='color:black'>%s</span>. %s", inp, name, str(err))
+            if self.error_is_safe:
+                flash_error("<span style='color:black'>%s</span> is not a valid input for <span style='color:black'>"+str(err)+"</span>. %s", inp, name)
+            else:
+                flash_error("<span style='color:black'>%s</span> is not a valid input for <span style='color:black'>%s</span>. %s", inp, name, str(err))
             info['err'] = ''
             raise
 
 @decorator_keywords
 def search_parser(f, clean_info=False, prep_ranges=False, prep_plus=False, pass_name=False,
-                  default_field=None, default_name=None, default_qfield=None):
-    return SearchParser(f, clean_info, prep_ranges, prep_plus, pass_name, default_field, default_name, default_qfield)
+                  default_field=None, default_name=None, default_qfield=None,error_is_safe=False):
+    return SearchParser(f, clean_info, prep_ranges, prep_plus, pass_name, default_field, default_name, default_qfield, error_is_safe)
 
 # Remove whitespace for simpler parsing
 # Remove brackets to avoid tricks (so we can echo it back safely)
@@ -515,7 +519,7 @@ def parse_bracketed_posints(inp, query, qfield, maxlength=None, exactlength=None
 def parse_gap_id(info, query, field='group', name='Group', qfield='group'):
     parse_bracketed_posints(info,query,field, split=False, exactlength=2, keepbrackets=True, name=name, qfield=qfield)
 
-@search_parser(clean_info=True, default_field='galois_group', default_name='Galois group', default_qfield='galois') # see SearchParser.__call__ for actual arguments when calling
+@search_parser(clean_info=True, default_field='galois_group', default_name='Galois group', default_qfield='galois', error_is_safe=True) # see SearchParser.__call__ for actual arguments when calling
 def parse_galgrp(inp, query, qfield):
     from lmfdb.galois_groups.transitive_group import complete_group_codes
     try:


Test patch: