Fossil SCM
In /ainfo elide the content if it's pending moderation and the user lacks permission to moderate or delete it. It's possible for unprivileged users to bypass this restriction by passing the same hash to /artifact, which will reveal the content.
Commit
641e7fced175b7e1d7fd17e3b3e432a632112d605fed5ec388b3c8deb5a8f308
Parent
c206c78e1598848…
1 file changed
+30
-26
+30
-26
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -740,46 +740,50 @@ | ||
| 740 | 740 | if( modPending && (isModerator || bUserIsOwner) ){ |
| 741 | 741 | @ <div class="section">Moderation</div> |
| 742 | 742 | @ <blockquote> |
| 743 | 743 | form_begin(0, "%R/ainfo/%s", zUuid); |
| 744 | 744 | @ <label><input type="radio" name="modaction" value="delete"> |
| 745 | - @ Delete this change</label><br> | |
| 745 | + @ Delete this attachment</label><br> | |
| 746 | 746 | if( isModerator ){ |
| 747 | 747 | @ <label><input type="radio" name="modaction" value="approve"> |
| 748 | - @ Approve this change</label><br> | |
| 748 | + @ Approve this attachment</label><br> | |
| 749 | 749 | } |
| 750 | 750 | @ <input type="submit" value="Submit"> |
| 751 | 751 | login_insert_csrf_secret(); |
| 752 | 752 | @ </form> |
| 753 | 753 | @ </blockquote> |
| 754 | 754 | } |
| 755 | 755 | |
| 756 | - @ <div class="section">Content Appended</div> | |
| 757 | - @ <blockquote> | |
| 756 | + @ <div class="section">Content:</div> | |
| 758 | 757 | blob_zero(&attach); |
| 759 | - if( fShowContent ){ | |
| 760 | - const char *z; | |
| 761 | - content_get(ridSrc, &attach); | |
| 762 | - blob_to_utf8_no_bom(&attach, 0); | |
| 763 | - z = blob_str(&attach); | |
| 764 | - if( zLn ){ | |
| 765 | - output_text_with_line_numbers(z, blob_size(&attach), zName, zLn, 1); | |
| 766 | - }else{ | |
| 767 | - @ <pre> | |
| 768 | - @ %h(z) | |
| 769 | - @ </pre> | |
| 770 | - } | |
| 771 | - }else if( strncmp(zMime, "image/", 6)==0 ){ | |
| 772 | - int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); | |
| 773 | - @ <i>(file is %d(sz) bytes of image data)</i><br> | |
| 774 | - @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img> | |
| 775 | - style_submenu_element("Image", "%R/raw/%s?m=%s", zSrc, zMime); | |
| 776 | - }else{ | |
| 777 | - int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); | |
| 778 | - @ <i>(file is %d(sz) bytes of binary data)</i> | |
| 779 | - } | |
| 780 | - @ </blockquote> | |
| 758 | + if( modPending && !moderation_user_could(rid, 1, 0) ){ | |
| 759 | + @ <p><span class="modpending">Content is awaiting moderator approval.</span></p> | |
| 760 | + }else{ | |
| 761 | + @ <blockquote> | |
| 762 | + if( fShowContent ){ | |
| 763 | + const char *z; | |
| 764 | + content_get(ridSrc, &attach); | |
| 765 | + blob_to_utf8_no_bom(&attach, 0); | |
| 766 | + z = blob_str(&attach); | |
| 767 | + if( zLn ){ | |
| 768 | + output_text_with_line_numbers(z, blob_size(&attach), zName, zLn, 1); | |
| 769 | + }else{ | |
| 770 | + @ <pre> | |
| 771 | + @ %h(z) | |
| 772 | + @ </pre> | |
| 773 | + } | |
| 774 | + }else if( strncmp(zMime, "image/", 6)==0 ){ | |
| 775 | + int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); | |
| 776 | + @ <i>(file is %d(sz) bytes of image data)</i><br> | |
| 777 | + @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img> | |
| 778 | + style_submenu_element("Image", "%R/raw/%s?m=%s", zSrc, zMime); | |
| 779 | + }else{ | |
| 780 | + int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); | |
| 781 | + @ <i>(file is %d(sz) bytes of binary data)</i> | |
| 782 | + } | |
| 783 | + @ </blockquote> | |
| 784 | + } | |
| 781 | 785 | manifest_destroy(pAttach); |
| 782 | 786 | blob_reset(&attach); |
| 783 | 787 | style_finish_page(); |
| 784 | 788 | } |
| 785 | 789 | |
| 786 | 790 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -740,46 +740,50 @@ | |
| 740 | if( modPending && (isModerator || bUserIsOwner) ){ |
| 741 | @ <div class="section">Moderation</div> |
| 742 | @ <blockquote> |
| 743 | form_begin(0, "%R/ainfo/%s", zUuid); |
| 744 | @ <label><input type="radio" name="modaction" value="delete"> |
| 745 | @ Delete this change</label><br> |
| 746 | if( isModerator ){ |
| 747 | @ <label><input type="radio" name="modaction" value="approve"> |
| 748 | @ Approve this change</label><br> |
| 749 | } |
| 750 | @ <input type="submit" value="Submit"> |
| 751 | login_insert_csrf_secret(); |
| 752 | @ </form> |
| 753 | @ </blockquote> |
| 754 | } |
| 755 | |
| 756 | @ <div class="section">Content Appended</div> |
| 757 | @ <blockquote> |
| 758 | blob_zero(&attach); |
| 759 | if( fShowContent ){ |
| 760 | const char *z; |
| 761 | content_get(ridSrc, &attach); |
| 762 | blob_to_utf8_no_bom(&attach, 0); |
| 763 | z = blob_str(&attach); |
| 764 | if( zLn ){ |
| 765 | output_text_with_line_numbers(z, blob_size(&attach), zName, zLn, 1); |
| 766 | }else{ |
| 767 | @ <pre> |
| 768 | @ %h(z) |
| 769 | @ </pre> |
| 770 | } |
| 771 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 772 | int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); |
| 773 | @ <i>(file is %d(sz) bytes of image data)</i><br> |
| 774 | @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img> |
| 775 | style_submenu_element("Image", "%R/raw/%s?m=%s", zSrc, zMime); |
| 776 | }else{ |
| 777 | int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); |
| 778 | @ <i>(file is %d(sz) bytes of binary data)</i> |
| 779 | } |
| 780 | @ </blockquote> |
| 781 | manifest_destroy(pAttach); |
| 782 | blob_reset(&attach); |
| 783 | style_finish_page(); |
| 784 | } |
| 785 | |
| 786 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -740,46 +740,50 @@ | |
| 740 | if( modPending && (isModerator || bUserIsOwner) ){ |
| 741 | @ <div class="section">Moderation</div> |
| 742 | @ <blockquote> |
| 743 | form_begin(0, "%R/ainfo/%s", zUuid); |
| 744 | @ <label><input type="radio" name="modaction" value="delete"> |
| 745 | @ Delete this attachment</label><br> |
| 746 | if( isModerator ){ |
| 747 | @ <label><input type="radio" name="modaction" value="approve"> |
| 748 | @ Approve this attachment</label><br> |
| 749 | } |
| 750 | @ <input type="submit" value="Submit"> |
| 751 | login_insert_csrf_secret(); |
| 752 | @ </form> |
| 753 | @ </blockquote> |
| 754 | } |
| 755 | |
| 756 | @ <div class="section">Content:</div> |
| 757 | blob_zero(&attach); |
| 758 | if( modPending && !moderation_user_could(rid, 1, 0) ){ |
| 759 | @ <p><span class="modpending">Content is awaiting moderator approval.</span></p> |
| 760 | }else{ |
| 761 | @ <blockquote> |
| 762 | if( fShowContent ){ |
| 763 | const char *z; |
| 764 | content_get(ridSrc, &attach); |
| 765 | blob_to_utf8_no_bom(&attach, 0); |
| 766 | z = blob_str(&attach); |
| 767 | if( zLn ){ |
| 768 | output_text_with_line_numbers(z, blob_size(&attach), zName, zLn, 1); |
| 769 | }else{ |
| 770 | @ <pre> |
| 771 | @ %h(z) |
| 772 | @ </pre> |
| 773 | } |
| 774 | }else if( strncmp(zMime, "image/", 6)==0 ){ |
| 775 | int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); |
| 776 | @ <i>(file is %d(sz) bytes of image data)</i><br> |
| 777 | @ <img src="%R/raw/%s(zSrc)?m=%s(zMime)"></img> |
| 778 | style_submenu_element("Image", "%R/raw/%s?m=%s", zSrc, zMime); |
| 779 | }else{ |
| 780 | int sz = db_int(0, "SELECT size FROM blob WHERE rid=%d", ridSrc); |
| 781 | @ <i>(file is %d(sz) bytes of binary data)</i> |
| 782 | } |
| 783 | @ </blockquote> |
| 784 | } |
| 785 | manifest_destroy(pAttach); |
| 786 | blob_reset(&attach); |
| 787 | style_finish_page(); |
| 788 | } |
| 789 | |
| 790 |