diff --git a/.gitignore b/.gitignore index 1721d45..10a7628 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ Trac-0.11.7.tar.gz /Trac-1.5.2.tar.gz /Trac-1.5.3.tar.gz /Trac-1.5.4.tar.gz +/Trac-1.6.tar.gz diff --git a/17541.diff b/17541.diff deleted file mode 100644 index 45c527d..0000000 --- a/17541.diff +++ /dev/null @@ -1,466 +0,0 @@ -Index: /trunk/trac/web/_fcgi.py -=================================================================== ---- /trunk/trac/web/_fcgi.py (revision 17540) -+++ /trunk/trac/web/_fcgi.py (revision 17541) -@@ -40,26 +40,16 @@ - __version__ = '$Revision: 2025 $' - -+import _thread -+import codecs -+import errno - import io -+import os -+import select -+import signal -+import socket -+import struct - import sys --import os --import signal --import struct --import select --import socket --import errno -+import threading - import traceback -- --try: -- import thread -- import threading -- thread_available = True --except ImportError: -- import dummy_thread as thread -- import dummy_threading as threading -- thread_available = False -- --# Apparently 2.3 doesn't define SHUT_WR? Assume it is 1 in this case. --if not hasattr(socket, 'SHUT_WR'): -- socket.SHUT_WR = 1 - - __all__ = ['WSGIServer'] -@@ -138,5 +128,5 @@ - self._shrinkThreshold = conn.server.inputStreamShrinkThreshold - -- self._buf = '' -+ self._buf = b'' - self._bufList = [] - self._pos = 0 # Current read position. -@@ -160,5 +150,5 @@ - def read(self, n=-1): - if self._pos == self._avail and self._eof: -- return '' -+ return b'' - while True: - if n < 0 or (self._avail - self._pos) < n: -@@ -177,5 +167,5 @@ - # Merge buffer list, if necessary. - if self._bufList: -- self._buf += ''.join(self._bufList) -+ self._buf += _bytes_join(self._bufList) - self._bufList = [] - r = self._buf[self._pos:newPos] -@@ -186,9 +176,9 @@ - def readline(self, length=None): - if self._pos == self._avail and self._eof: -- return '' -+ return b'' - while True: - # Unfortunately, we need to merge the buffer list early. - if self._bufList: -- self._buf += ''.join(self._bufList) -+ self._buf += _bytes_join(self._bufList) - self._bufList = [] - # Find newline. -@@ -317,4 +307,5 @@ - def write(self, data): - assert not self.closed -+ assert type(data) is bytes - - if not data: -@@ -337,5 +328,5 @@ - # Only need to flush if this OutputStream is actually buffered. - if self._buffered: -- data = ''.join(self._bufList) -+ data = _bytes_join(self._bufList) - self._bufList = [] - self._write(data) -@@ -397,22 +388,22 @@ - are returned. - """ -- nameLength = ord(s[pos]) -- if nameLength & 128: -- nameLength = struct.unpack('!L', s[pos:pos+4])[0] & 0x7fffffff -+ namelen = s[pos] -+ if namelen & 128: -+ namelen = struct.unpack('!L', s[pos:pos+4])[0] & 0x7fffffff - pos += 4 - else: - pos += 1 - -- valueLength = ord(s[pos]) -- if valueLength & 128: -- valueLength = struct.unpack('!L', s[pos:pos+4])[0] & 0x7fffffff -+ valuelen = s[pos] -+ if valuelen & 128: -+ valuelen = struct.unpack('!L', s[pos:pos+4])[0] & 0x7fffffff - pos += 4 - else: - pos += 1 - -- name = s[pos:pos+nameLength] -- pos += nameLength -- value = s[pos:pos+valueLength] -- pos += valueLength -+ name = str(s[pos:pos+namelen], 'iso-8859-1') -+ pos += namelen -+ value = str(s[pos:pos+valuelen], 'iso-8859-1') -+ pos += valuelen - - return pos, (name, value) -@@ -424,17 +415,25 @@ - The encoded string is returned. - """ -- nameLength = len(name) -- if nameLength < 128: -- s = chr(nameLength) -+ name = name.encode('iso-8859-1') -+ value = value.encode('iso-8859-1') -+ -+ namelen = len(name) -+ if namelen < 128: -+ namelen = _code2bytes(namelen) - else: -- s = struct.pack('!L', nameLength | 0x80000000) -- -- valueLength = len(value) -- if valueLength < 128: -- s += chr(valueLength) -+ namelen = struct.pack('!L', namelen | 0x80000000) -+ -+ valuelen = len(value) -+ if valuelen < 128: -+ valuelen = _code2bytes(valuelen) - else: -- s += struct.pack('!L', valueLength | 0x80000000) -- -- return s + name + value -+ valuelen = struct.pack('!L', valuelen | 0x80000000) -+ -+ return namelen + valuelen + name + value -+ -+_bytes_join = b''.join -+_str_join = ''.join -+_code2bytes = lambda code: b'%c' % code -+_utf8_writer = lambda f: codecs.getwriter('utf-8')(f) - - class Record(object): -@@ -450,5 +449,5 @@ - self.contentLength = 0 - self.paddingLength = 0 -- self.contentData = '' -+ self.contentData = b'' - - @staticmethod -@@ -464,5 +463,5 @@ - data = sock.recv(length) - except socket.error as e: -- if e[0] == errno.EAGAIN: -+ if e.errno == errno.EAGAIN: - select.select([sock], [], []) - continue -@@ -475,5 +474,5 @@ - recvLen += dataLen - length -= dataLen -- return ''.join(dataList), recvLen -+ return _bytes_join(dataList), recvLen - - def read(self, sock): -@@ -516,4 +515,5 @@ - Writes data to a socket and does not return until all the data is sent. - """ -+ assert type(data) is bytes - length = len(data) - while length: -@@ -521,5 +521,5 @@ - sent = sock.send(data) - except socket.error as e: -- if e[0] == errno.EAGAIN: -+ if e.errno == errno.EAGAIN: - select.select([], [sock], []) - continue -@@ -545,5 +545,5 @@ - self._sendall(sock, self.contentData) - if self.paddingLength: -- self._sendall(sock, '\x00'*self.paddingLength) -+ self._sendall(sock, b'\x00' * self.paddingLength) - - class Request(object): -@@ -563,5 +563,6 @@ - self.stdin = inputStreamClass(conn) - self.stdout = OutputStream(conn, self, FCGI_STDOUT) -- self.stderr = OutputStream(conn, self, FCGI_STDERR, buffered=True) -+ self.stderr = _utf8_writer(OutputStream(conn, self, FCGI_STDERR, -+ buffered=True)) - self.data = inputStreamClass(conn) - -@@ -585,5 +586,5 @@ - self._end(appStatus, protocolStatus) - except socket.error as e: -- if e[0] != errno.EPIPE: -+ if e.errno != errno.EPIPE: - raise - -@@ -645,6 +646,6 @@ - try: - while True: -- r, w, e = select.select([self._sock], [], []) -- if not r or not self._sock.recv(1024): -+ rlist, wlist, xlist = select.select([self._sock], [], []) -+ if not rlist or not self._sock.recv(1024): - break - except: -@@ -660,6 +661,6 @@ - except EOFError: - break -- except (select.error, socket.error) as e: -- if e[0] == errno.EBADF: # Socket was closed by Request. -+ except select.error as e: -+ if e.errno == errno.EBADF: # Socket was closed by Request. - break - raise -@@ -675,10 +676,10 @@ - while self._keepGoing: - try: -- r, w, e = select.select([self._sock], [], [], 1.0) -+ rlist, wlist, xlist = select.select([self._sock], [], [], 1.0) - except ValueError: - # Sigh. ValueError gets thrown sometimes when passing select - # a closed socket. - raise EOFError -- if r: break -+ if rlist: break - if not self._keepGoing: - return -@@ -876,5 +877,5 @@ - - def _start_request(self, req): -- thread.start_new_thread(req.run, ()) -+ _thread.start_new_thread(req.run, ()) - - def _do_params(self, inrec): -@@ -948,31 +949,22 @@ - self.handler = handler - self.maxwrite = maxwrite -- if thread_available: -- try: -- import resource -- # Attempt to glean the maximum number of connections -- # from the OS. -- maxConns = resource.getrlimit(resource.RLIMIT_NOFILE)[0] -- except (ImportError, AttributeError): -- maxConns = 100 # Just some made up number. -- maxReqs = maxConns -- if multiplexed: -- self._connectionClass = MultiplexedConnection -- maxReqs *= 5 # Another made up number. -- else: -- self._connectionClass = Connection -- self.capability = { -- FCGI_MAX_CONNS: maxConns, -- FCGI_MAX_REQS: maxReqs, -- FCGI_MPXS_CONNS: multiplexed and 1 or 0 -- } -+ try: -+ import resource -+ # Attempt to glean the maximum number of connections -+ # from the OS. -+ maxConns = resource.getrlimit(resource.RLIMIT_NOFILE)[0] -+ except (ImportError, AttributeError): -+ maxConns = 100 # Just some made up number. -+ maxReqs = maxConns -+ if multiplexed: -+ self._connectionClass = MultiplexedConnection -+ maxReqs *= 5 # Another made up number. - else: - self._connectionClass = Connection -- self.capability = { -- # If threads aren't available, these are pretty much correct. -- FCGI_MAX_CONNS: 1, -- FCGI_MAX_REQS: 1, -- FCGI_MPXS_CONNS: 0 -- } -+ self.capability = { -+ FCGI_MAX_CONNS: maxConns, -+ FCGI_MAX_REQS: maxReqs, -+ FCGI_MPXS_CONNS: 1 if multiplexed else 0, -+ } - self._bindAddress = bindAddress - self._umask = umask -@@ -987,8 +979,8 @@ - sock.getpeername() - except socket.error as e: -- if e[0] == errno.ENOTSOCK: -+ if e.errno == errno.ENOTSOCK: - # Not a socket, assume CGI context. - isFCGI = False -- elif e[0] != errno.ENOTCONN: -+ elif e.errno != errno.ENOTCONN: - raise - -@@ -1072,15 +1064,15 @@ - while self._keepGoing: - try: -- r, w, e = select.select([sock], [], [], timeout) -+ rlist, wlist, xlist = select.select([sock], [], [], timeout) - except select.error as e: -- if e[0] == errno.EINTR: -+ if e.errno == errno.EINTR: - continue - raise - -- if r: -+ if rlist: - try: - clientSock, addr = sock.accept() - except socket.error as e: -- if e[0] in (errno.EINTR, errno.EAGAIN): -+ if e.errno in (errno.EINTR, errno.EAGAIN): - continue - raise -@@ -1094,5 +1086,5 @@ - # messages (either in a new thread or this thread). - conn = self._connectionClass(clientSock, addr, self) -- thread.start_new_thread(conn.run, ()) -+ _thread.start_new_thread(conn.run, ()) - - self._mainloopPeriodic() -@@ -1134,7 +1126,8 @@ - should be overridden. - """ -- import cgitb -- req.stdout.write('Content-Type: text/html\r\n\r\n' + -- cgitb.html(sys.exc_info())) -+ out = _utf8_writer(req.stdout) -+ out.write('Content-Type: text/plain; charset=utf-8\r\n\r\n') -+ traceback.print_exc(file=out) -+ out.flush() - - class WSGIServer(Server): -@@ -1164,5 +1157,5 @@ - - # Used to force single-threadedness -- self._app_lock = thread.allocate_lock() -+ self._app_lock = _thread.allocate_lock() - - def handler(self, req): -@@ -1175,5 +1168,5 @@ - environ.update(self.environ) - -- environ['wsgi.version'] = (1,0) -+ environ['wsgi.version'] = (1, 0) - environ['wsgi.input'] = req.stdin - if self._bindAddress is None: -@@ -1183,5 +1176,5 @@ - environ['wsgi.errors'] = stderr - environ['wsgi.multithread'] = not isinstance(req, CGIRequest) and \ -- thread_available and self.multithreaded -+ self.multithreaded - # Rationale for the following: If started by the web server - # (self._bindAddress is None) in either FastCGI or CGI mode, the -@@ -1207,26 +1200,15 @@ - - def write(data): -- assert type(data) is str, 'write() argument must be string' -+ assert type(data) is bytes, 'write() argument must be bytes' - assert headers_set, 'write() before start_response()' - - if not headers_sent: -- status, responseHeaders = headers_sent[:] = headers_set -- found = False -- for header,value in responseHeaders: -- if header.lower() == 'content-length': -- found = True -- break -- if not found and result is not None: -- try: -- if len(result) == 1: -- responseHeaders.append(('Content-Length', -- str(len(data)))) -- except: -- pass -- s = 'Status: %s\r\n' % status -- for header in responseHeaders: -- s += '%s: %s\r\n' % header -- s += '\r\n' -- req.stdout.write(s) -+ status, headers = headers_sent[:] = headers_set -+ def generator(): -+ yield 'Status: %s\r\n' % status -+ for header in headers: -+ yield '%s: %s\r\n' % header -+ yield '\r\n' -+ req.stdout.write(_str_join(generator()).encode('iso-8859-1')) - - req.stdout.write(data) -@@ -1266,11 +1248,11 @@ - write(data) - if not headers_sent: -- write('') # in case body was empty -+ write(b'') # in case body was empty - finally: - if hasattr(result, 'close'): - result.close() - except socket.error as e: -- if e[0] != errno.EPIPE: -- raise # Don't let EPIPE propagate beyond server -+ if e.errno != errno.EPIPE: -+ raise # Don't let EPIPE propagate beyond server - finally: - if not self.multithreaded: -Index: /trunk/trac/web/fcgi_frontend.py -=================================================================== ---- /trunk/trac/web/fcgi_frontend.py (revision 17540) -+++ /trunk/trac/web/fcgi_frontend.py (revision 17541) -@@ -27,5 +27,4 @@ - use_flup = False - -- - class FlupMiddleware(object): - """Flup doesn't URL unquote the PATH_INFO, so we need to do it.""" -@@ -43,8 +42,9 @@ - try: - from flup.server.fcgi import WSGIServer -+ except ImportError: -+ use_flup = False -+ else: - params['maxThreads'] = 15 - dispatch_request = FlupMiddleware(dispatch_request) -- except ImportError: -- use_flup = False - - if not use_flup: -Index: /trunk/trac/web/templates/deploy_trac.fcgi -=================================================================== ---- /trunk/trac/web/templates/deploy_trac.fcgi (revision 17540) -+++ /trunk/trac/web/templates/deploy_trac.fcgi (revision 17541) -@@ -34,14 +34,12 @@ - raise - except Exception as e: -- print("Content-Type: text/plain\r\n\r\n", end=' ') -+ print("Content-Type: text/plain", end="\r\n") -+ print("", end="\r\n") - print("Oops...") -- print() -+ print("") - print("Trac detected an internal error:") -- print() -+ print("") - print(e) -- print() -+ print("", flush=True) - import traceback -- import io -- tb = io.Bytes() -- traceback.print_exc(file=tb) -- print(tb.getvalue()) -+ traceback.print_exc(file=sys.stdout) diff --git a/changeset_17575.diff b/changeset_17575.diff deleted file mode 100644 index 8b6131e..0000000 --- a/changeset_17575.diff +++ /dev/null @@ -1,13 +0,0 @@ ---- Trac-1.5.3/trac/util/html.py~ 2021-05-09 18:08:49.000000000 -0500 -+++ Trac-1.5.3/trac/util/html.py 2022-12-07 14:36:09.258643955 -0600 -@@ -25,6 +25,10 @@ - from html.parser import HTMLParser - - from markupsafe import Markup, escape as escape_quotes -+try: -+ from markupsafe import soft_str as soft_unicode -+except ImportError: -+ from markupsafe import soft_unicode - - try: - from babel.support import LazyProxy diff --git a/sources b/sources index d672dab..262ff9d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Trac-1.5.4.tar.gz) = 0dc53dff0b31aa1668b104c06f693a8d7080260c87bb979724e270a645744fa984c4d6c5dd74ef8e8af5b589d1166fae56a992e31c65ec9d04b75c031cbbbfce +SHA512 (Trac-1.6.tar.gz) = a9bff574b581daecc8a9a20c158913a853174c2f6da3ae60e8b2099353a46d0cbd9b46a82c41f0cca17f0df28eece3a83a133191720a716d7a53dfed85b474cf diff --git a/trac.spec b/trac.spec index 0be86c4..a7f3801 100644 --- a/trac.spec +++ b/trac.spec @@ -1,6 +1,6 @@ Name: trac -Version: 1.5.4 -Release: 4%{?dist} +Version: 1.6 +Release: 1%{?dist} Summary: Enhanced wiki and issue tracking system License: BSD-3-Clause URL: http://trac.edgewall.com/ @@ -82,6 +82,9 @@ mv $RPM_BUILD_ROOT{%{_bindir}/tracd,%{_sbindir}/tracd} %config(noreplace) /etc/trac/* %changelog +* Mon Sep 25 2023 Gwyn Ciesla - 1.6-1 +- 1.6 + * Sat Jul 22 2023 Fedora Release Engineering - 1.5.4-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild