--- ./MoinMoin/Page.py.orig 2014-10-17 22:45:32.000000000 +0300 +++ ./MoinMoin/Page.py 2016-02-05 20:20:23.598923780 +0200 @@ -108,8 +108,7 @@ class ItemCache: (for 'meta') or the complete cache ('pagelists'). @param request: the request object """ - from MoinMoin.logfile import editlog - elog = editlog.EditLog(request) + elog = request.editlog old_pos = self.log_pos new_pos, items = elog.news(old_pos) if items: @@ -626,7 +625,12 @@ class Page(object): """ return self.exists(domain='standard', includeDeleted=includeDeleted) - def exists(self, rev=0, domain=None, includeDeleted=False): + def _in_backend(self): + if self.page_name in self.request.graphdata: + return self.request.graphdata.is_saved(self.page_name) + return 0 + + def exists(self, rev=0, domain=None, includeDeleted=False, includeBackend=True): """ Does this page exist? This is the lower level method for checking page existence. Use @@ -656,6 +660,12 @@ class Page(object): return True return False else: + # If it's in the backend, it exists + if self._in_backend(): + return True + elif includeBackend: + return False + # Look for non-deleted pages only, using get_rev if not rev and self.rev: rev = self.rev @@ -789,13 +799,20 @@ class Page(object): @rtype: string @return: formatted link """ + # Optimising closing of links + if kw.get('on', None) == 0: + formatter=getattr(self, 'formatter', None) + if formatter: + return formatter.url(0, '', None) + if not text: text = self.split_title() text = wikiutil.escape(text) - # Add css class for non existing page - if not self.exists(): - kw['css_class'] = 'nonexistent' + # Add css class for non existing page (if not done by formatter.pagelink) + if not kw.has_key('css_class'): + if not self.exists(): + kw['css_class'] = 'nonexistent' attachment_indicator = kw.get('attachment_indicator') if attachment_indicator is None: @@ -1826,7 +1843,7 @@ class RootPage(Page): return underlay, path - def getPageList(self, user=None, exists=1, filter=None, include_underlay=True, return_objects=False): + def getPageList(self, user=None, exists=1, filter=None, include_underlay=True, return_objects=False, includeBackend=True): """ List user readable pages under current page Currently only request.rootpage is used to list pages, but if we @@ -1895,7 +1912,7 @@ class RootPage(Page): continue # Filter deleted pages - if exists and not page.exists(): + if exists and not page.exists(includeBackend=includeBackend): continue # Filter out page user may not read. --- MoinMoin/PageEditor.py.orig 2020-11-08 19:23:14.000000000 +0200 +++ MoinMoin/PageEditor.py 2020-11-11 09:13:04.000000000 +0200 @@ -17,7 +17,7 @@ """ import os, time, codecs, errno - +import unicodedata from MoinMoin import caching, config, wikiutil, error from MoinMoin.Page import Page @@ -53,6 +53,17 @@ """ +############################################################################# +### Filtering unprintable characters from page content +############################################################################# + +ALLOWED_CONTROL_CHARS = '\t\n\r' + +def filter_unprintable(text): + return ''.join(x for x in text + if (not unicodedata.category(x) in ['Cc', 'Cn', 'Cs'] + or x in ALLOWED_CONTROL_CHARS)) + ############################################################################# ### PageEditor - Edit pages @@ -1065,6 +1076,26 @@ """ request = self.request _ = self._ + + # Depending on the configuration, filter unprintable + # characters from text content or warn of them. Unprintable + # characters are often undesired, and result from + # eg. copy-pasting text from productivity tools. + _handle_unprintable = getattr(self.request.cfg, + 'gwiki_handle_unprintable', '') + if _handle_unprintable in ['warn', 'filter']: + _newtext = filter_unprintable(newtext) + if _handle_unprintable == 'filter': + newtext = _newtext + elif _newtext != newtext: + _pos = 0 + for i in len(_newtext): + _pos = i + if _newtext[i] != newtext[i]: + break + raise self.SaveError(_("Bad character in text at position %s.")% + (_pos)) + self._save_draft(newtext, rev, **kw) action = kw.get('action', 'SAVE') deleted = kw.get('deleted', False) --- MoinMoin/auth/__init__.py.orig 2020-11-08 19:23:14.000000000 +0200 +++ MoinMoin/auth/__init__.py 2020-11-11 09:28:06.000000000 +0200 @@ -374,7 +374,7 @@ auth_username = self.transform_username(auth_username) logging.debug("auth_username (after decode/transform) = %r" % auth_username) u = user.User(request, auth_username=auth_username, - auth_method=self.name, auth_attribs=('name', 'password')) + auth_method=self.name, auth_attribs=('name')) logging.debug("u: %r" % u) if u and self.autocreate: --- ./MoinMoin/config/__init__.py.orig 2014-10-17 22:45:32.000000000 +0300 +++ ./MoinMoin/config/__init__.py 2015-12-06 11:57:48.923411442 +0200 @@ -25,7 +25,7 @@ umask = 0770 # list of acceptable password hashing schemes for cfg.password_scheme, # here we only give reasonably good schemes, which is passlib (if we # have passlib) and ssha (if we only have builtin stuff): -password_schemes_configurable = ['{PASSLIB}', '{SSHA}', ] +password_schemes_configurable = ['{PASSLIB}', '{SSHA}', '{SHA}' ] # ordered list of supported password hashing schemes, best (passlib) should be # first, best builtin one should be second. this is what we support if we @@ -58,6 +58,9 @@ page_invalid_chars_regex = re.compile( ur""" \u0000 | # NULL + \# | # http://tools.ietf.org/html/rfc3986#section-3.3 + \? | + # Bidi control characters \u202A | # LRE \u202B | # RLE --- MoinMoin/formatter/__init__.py.orig 2020-11-08 19:23:14.000000000 +0200 +++ MoinMoin/formatter/__init__.py 2020-11-11 09:18:45.000000000 +0200 @@ -137,7 +137,10 @@ # Try to decode text. It might return junk, but we don't # have enough information with attachments. content = wikiutil.decodeUnknownInput(content) - colorizer = Parser(content, self.request, filename=filename) + if '.csv' in getattr(Parser, 'extensions', list()): + colorizer = Parser(content, self.request, filename=filename, format_args=kw.get('format_args', '')) + else: + colorizer = Parser(content, self.request, filename=filename) colorizer.format(self) except IOError: pass --- MoinMoin/formatter/text_html.py.orig 2020-11-08 19:23:14.000000000 +0200 +++ MoinMoin/formatter/text_html.py 2020-11-11 09:19:27.000000000 +0200 @@ -6,12 +6,14 @@ @license: GNU GPL, see COPYING for details. """ import os.path, re +import urllib +import urlparse from MoinMoin import log logging = log.getLogger(__name__) from MoinMoin.formatter import FormatterBase -from MoinMoin import wikiutil, i18n +from MoinMoin import wikiutil, i18n, config from MoinMoin.Page import Page from MoinMoin.action import AttachFile @@ -473,16 +475,17 @@ del kw['generated'] if page is None: page = Page(self.request, pagename, formatter=self) - if self.request.user.show_nonexist_qm and on and not page.exists(): - self.pagelink_preclosed = True - return (page.link_to(self.request, on=1, **kw) + - self.text("?") + - page.link_to(self.request, on=0, **kw)) + if on and not page.exists(): + kw['css_class'] = 'nonexistent' + if self.request.user.show_nonexist_qm: + self.pagelink_preclosed = True + return (page.link_to(self.request, on=1, **kw) + + self.text("?") + + page.link_to(self.request, on=0, **kw)) elif not on and self.pagelink_preclosed: self.pagelink_preclosed = False return "" - else: - return page.link_to(self.request, on=on, **kw) + return page.link_to(self.request, on=on, **kw) def interwikilink(self, on, interwiki='', pagename='', **kw): """ @@ -533,12 +536,25 @@ logging.warning("Deprecation warning: MoinMoin.formatter.text_html.url being called with do_escape=1/True parameter, please review caller.") else: logging.warning("Deprecation warning: MoinMoin.formatter.text_html.url being called with do_escape=0/False parameter, please remove it from the caller.") + + def quote_urlparts(url): + """ + hrefs should be quoted as per RFC3986. + """ + urlp = list(urlparse.urlparse(url)) + for part in (2, 4): + if isinstance(urlp[part], unicode): + urlp[part] = urlp[part].encode(config.charset) + urlp[2] = urllib.quote(urlp[2]) + urlp[4] = urllib.urlencode(urlparse.parse_qs(urlp[4]), doseq=1) + return urlparse.urlunparse(urlp) + if on: attrs = self._langAttr() # Handle the URL mapping if url is None and 'href' in kw: - url = kw['href'] + url = quote_urlparts(kw['href']) del kw['href'] if url is not None: url = wikiutil.mapURL(self.request, url) --- MoinMoin/macro/Include.py.orig 2014-10-17 22:45:33.000000000 +0300 +++ MoinMoin/macro/Include.py 2016-01-26 12:46:30.000000000 +0200 @@ -1,31 +1,37 @@ -# -*- coding: iso-8859-1 -*- +# -*- coding: utf-8 -*- """ - MoinMoin - Include macro + Include macro for MoinMoin/GraphingWiki - This macro includes the formatted content of the given page(s). See + Partial rewrite of orginal Include macro. - http://purl.net/wiki/moinmaster/HelpOnMacros/Include - - for detailed docs. + New features: + * Including nonexisting pages with an editlink + * Specifying a template for editing, eg. + <> + * Specifying a revision for included pages, eg. + <> @copyright: 2000-2004 Juergen Hermann , - 2000-2001 Richard Jones + 2000-2001 Richard Jones , + 2009-2011 Juhani Eronen , + 2015-2016 Mika Seppänen @license: GNU GPL, see COPYING for details. """ -#Dependencies = ["pages"] # included page -Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks +Dependencies = ["time"] # works around MoinMoinBugs/TableOfContentsLacksLinks generates_headings = True -import re, StringIO +import re +import StringIO + from MoinMoin import wikiutil from MoinMoin.Page import Page +from graphingwiki import actionname, id_escape, SEPARATOR +from graphingwiki.util import render_error, render_warning +from graphingwiki.util import form_writer as wr -_sysmsg = '

%s

' - -## keep in sync with TableOfContents macro! _arg_heading = r'(?P,)\s*(|(?P[\'"])(?P.+?)(?P=hquote))' _arg_level = r',\s*(?P\d*)' _arg_from = r'(,\s*from=(?P[\'"])(?P.+?)(?P=fquote))?' @@ -35,23 +41,27 @@ _arg_skipitems = r'(,\s*skipitems=(?P\d+))?' _arg_titlesonly = r'(,\s*(?Ptitlesonly))?' _arg_editlink = r'(,\s*(?Peditlink))?' -_args_re_pattern = r'^(?P[^,]+)(%s(%s)?%s%s%s%s%s%s%s)?$' % ( +_arg_rev = r'(,\s*rev=(?P\d+))?' +_arg_template = r'(,\s*template=(?P[\'"])(?P