Edgewall Software

Ticket #7078: 7078-limit-zip-download-r10551.patch

File 7078-limit-zip-download-r10551.patch, 3.6 KB (added by rblank, 16 months ago)

Limit the total size of attachments to be downloadable as a .zip.

  • trac/attachment.py

    diff --git a/trac/attachment.py b/trac/attachment.py
    a b class AttachmentModule(Component): 
    363363        """Maximum allowed file size (in bytes) for ticket and wiki  
    364364        attachments.""") 
    365365 
     366    max_zip_size = IntOption('attachment', 'max_zip_size', 2097152, 
     367        """Maximum allowed total size (in bytes) for an attachment list to be 
     368        downloadable as a `.zip`. Set this to -1 to disable download as `.zip`. 
     369        (''since 0.13'')""") 
     370 
    366371    render_unsafe_content = BoolOption('attachment', 'render_unsafe_content', 
    367372                                       'false', 
    368373        """Whether attachments should be rendered in the browser, or 
    class AttachmentModule(Component): 
    482487        for attachment in Attachment.select(self.env, parent.realm, parent.id): 
    483488            if 'ATTACHMENT_VIEW' in context.perm(attachment.resource): 
    484489                attachments.append(attachment) 
     490        total_size = sum(attachment.size for attachment in attachments) 
    485491        new_att = parent.child('attachment') 
    486492        return {'attach_href': get_resource_url(self.env, new_att, 
    487493                                                context.href), 
    488494                'download_href': get_resource_url(self.env, new_att, 
    489                                                   context.href, format='zip'), 
     495                                                  context.href, format='zip') 
     496                                 if total_size <= self.max_zip_size else None, 
    490497                'can_create': 'ATTACHMENT_CREATE' in context.perm(new_att), 
    491498                'attachments': attachments, 
    492499                'parent': context.resource} 
    class AttachmentModule(Component): 
    711718            'attachment': attachment, 'max_size': self.max_size} 
    712719 
    713720    def _download_as_zip(self, req, parent, attachments=None): 
     721        if attachments is None: 
     722            attachments = Attachment.select(self.env, parent.realm, parent.id) 
     723        total_size = sum(attachment.size for attachment in attachments) 
     724        if total_size > self.max_zip_size: 
     725            raise TracError(_('Maximum total attachment size: %(num)s bytes', 
     726                              num=self.max_zip_size), _('Download failed')) 
     727         
    714728        req.send_response(200) 
    715729        req.send_header('Content-Type', 'application/zip') 
    716730        filename = 'attachments-%s-%s.zip' % \ 
    717731                   (parent.realm, re.sub(r'[/\\:]', '-', unicode(parent.id))) 
    718732        req.send_header('Content-Disposition', 
    719733                        content_disposition('inline', filename)) 
    720         if attachments is None: 
    721             attachments = Attachment.select(self.env, parent.realm, parent.id) 
    722734 
    723735        from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED 
    724736 
  • trac/templates/list_of_attachments.html

    diff --git a/trac/templates/list_of_attachments.html b/trac/templates/list_of_attachments.html
    a b Arguments: 
    3535              </li> 
    3636            </py:for> 
    3737          </ul> 
    38           <p py:if="alist.attachments"> 
     38          <p py:if="alist.download_href"> 
    3939            Download all attachments as: <a rel="nofollow" href="$alist.download_href">.zip</a> 
    4040          </p> 
    4141        </div> 
    Arguments: 
    5151              </dd> 
    5252            </py:for> 
    5353          </dl> 
    54           <p py:if="alist.attachments"> 
     54          <p py:if="alist.attachments and alist.download_href"> 
    5555            Download all attachments as: <a rel="nofollow" href="$alist.download_href">.zip</a> 
    5656          </p> 
    5757          <xi:include href="attach_file_form.html"/>