Fossil SCM
Do not allow forum posts that are replies or the start of a new message if they contain no content. An edit with no content is ok, as that means the post is to be deleted.
Commit
d2c81b9d6aed153cfe9fe53667f7778fc7c4f898614fffeea20719eb9321339e
Parent
c40863abdb3a581…
1 file changed
+19
-6
+19
-6
| --- src/forum.c | ||
| +++ src/forum.c | ||
| @@ -753,10 +753,19 @@ | ||
| 753 | 753 | if( P("domod") ) return 1; |
| 754 | 754 | if( g.perm.WrTForum ) return 0; |
| 755 | 755 | if( g.perm.ModForum ) return 0; |
| 756 | 756 | return 1; |
| 757 | 757 | } |
| 758 | + | |
| 759 | +/* | |
| 760 | +** Return true if the string is white-space only. | |
| 761 | +*/ | |
| 762 | +static int whitespace_only(const char *z){ | |
| 763 | + if( z==0 ) return 1; | |
| 764 | + while( z[0] && fossil_isspace(z[0]) ){ z++; } | |
| 765 | + return z[0]==0; | |
| 766 | +} | |
| 758 | 767 | |
| 759 | 768 | /* |
| 760 | 769 | ** Add a new Forum Post artifact to the repository. |
| 761 | 770 | ** |
| 762 | 771 | ** Return true if a redirect occurs. |
| @@ -773,12 +782,16 @@ | ||
| 773 | 782 | char *zI; |
| 774 | 783 | char *zG; |
| 775 | 784 | int iBasis; |
| 776 | 785 | Blob x, cksum, formatCheck, errMsg; |
| 777 | 786 | Manifest *pPost; |
| 787 | + int nContent = zContent ? (int)strlen(zContent) : 0; | |
| 778 | 788 | |
| 779 | 789 | schema_forum(); |
| 790 | + if( iEdit==0 && whitespace_only(zContent) ){ | |
| 791 | + return 0; | |
| 792 | + } | |
| 780 | 793 | if( iInReplyTo==0 && iEdit>0 ){ |
| 781 | 794 | iBasis = iEdit; |
| 782 | 795 | iInReplyTo = db_int(0, "SELECT firt FROM forumpost WHERE fpid=%d", iEdit); |
| 783 | 796 | }else{ |
| 784 | 797 | iBasis = iInReplyTo; |
| @@ -819,11 +832,11 @@ | ||
| 819 | 832 | }else{ |
| 820 | 833 | zUser = login_name(); |
| 821 | 834 | } |
| 822 | 835 | } |
| 823 | 836 | blob_appendf(&x, "U %F\n", zUser); |
| 824 | - blob_appendf(&x, "W %d\n%s\n", strlen(zContent), zContent); | |
| 837 | + blob_appendf(&x, "W %d\n%s\n", nContent, zContent); | |
| 825 | 838 | md5sum_blob(&x, &cksum); |
| 826 | 839 | blob_appendf(&x, "Z %b\n", &cksum); |
| 827 | 840 | blob_reset(&cksum); |
| 828 | 841 | |
| 829 | 842 | /* Verify that the artifact we are creating is well-formed */ |
| @@ -953,21 +966,21 @@ | ||
| 953 | 966 | return; |
| 954 | 967 | } |
| 955 | 968 | if( P("submit") && cgi_csrf_safe(1) ){ |
| 956 | 969 | if( forum_post(zTitle, 0, 0, 0, zMimetype, zContent) ) return; |
| 957 | 970 | } |
| 958 | - if( P("preview") ){ | |
| 971 | + if( P("preview") && !whitespace_only(zContent) ){ | |
| 959 | 972 | @ <h1>Preview:</h1> |
| 960 | 973 | forum_render(zTitle, zMimetype, zContent, "forumEdit", 1); |
| 961 | 974 | } |
| 962 | 975 | style_header("New Forum Thread"); |
| 963 | 976 | @ <form action="%R/forume1" method="POST"> |
| 964 | 977 | @ <h1>New Thread:</h1> |
| 965 | 978 | forum_from_line(); |
| 966 | 979 | forum_entry_widget(zTitle, zMimetype, zContent); |
| 967 | 980 | @ <input type="submit" name="preview" value="Preview"> |
| 968 | - if( P("preview") ){ | |
| 981 | + if( P("preview") && !whitespace_only(zContent) ){ | |
| 969 | 982 | @ <input type="submit" name="submit" value="Submit"> |
| 970 | 983 | }else{ |
| 971 | 984 | @ <input type="submit" name="submit" value="Submit" disabled> |
| 972 | 985 | } |
| 973 | 986 | if( g.perm.Debug ){ |
| @@ -1053,11 +1066,11 @@ | ||
| 1053 | 1066 | } |
| 1054 | 1067 | return; |
| 1055 | 1068 | } |
| 1056 | 1069 | } |
| 1057 | 1070 | isDelete = P("nullout")!=0; |
| 1058 | - if( P("submit") && isCsrfSafe ){ | |
| 1071 | + if( P("submit") && (isDelete || !whitespace_only(zContent)) && isCsrfSafe ){ | |
| 1059 | 1072 | int done = 1; |
| 1060 | 1073 | const char *zMimetype = PD("mimetype",DEFAULT_FORUM_MIMETYPE); |
| 1061 | 1074 | const char *zContent = PDT("content",""); |
| 1062 | 1075 | if( P("reply") ){ |
| 1063 | 1076 | done = forum_post(0, fpid, 0, 0, zMimetype, zContent); |
| @@ -1124,11 +1137,11 @@ | ||
| 1124 | 1137 | zDisplayName = display_name_from_login(pPost->zUser); |
| 1125 | 1138 | @ <h3 class='forumPostHdr'>By %h(zDisplayName) on %h(zDate)</h3> |
| 1126 | 1139 | fossil_free(zDisplayName); |
| 1127 | 1140 | fossil_free(zDate); |
| 1128 | 1141 | forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit", 1); |
| 1129 | - if( P("preview") ){ | |
| 1142 | + if( P("preview") && !whitespace_only(zContent) ){ | |
| 1130 | 1143 | @ <h2>Preview:</h2> |
| 1131 | 1144 | forum_render(0, zMimetype,zContent, "forumEdit", 1); |
| 1132 | 1145 | } |
| 1133 | 1146 | @ <h2>Enter Reply:</h2> |
| 1134 | 1147 | @ <form action="%R/forume2" method="POST"> |
| @@ -1139,11 +1152,11 @@ | ||
| 1139 | 1152 | } |
| 1140 | 1153 | if( !isDelete ){ |
| 1141 | 1154 | @ <input type="submit" name="preview" value="Preview"> |
| 1142 | 1155 | } |
| 1143 | 1156 | @ <input type="submit" name="cancel" value="Cancel"> |
| 1144 | - if( P("preview") || isDelete ){ | |
| 1157 | + if( (P("preview") && !whitespace_only(zContent)) || isDelete ){ | |
| 1145 | 1158 | @ <input type="submit" name="submit" value="Submit"> |
| 1146 | 1159 | } |
| 1147 | 1160 | if( g.perm.Debug ){ |
| 1148 | 1161 | /* For the test-forumnew page add these extra debugging controls */ |
| 1149 | 1162 | @ <div class="debug"> |
| 1150 | 1163 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -753,10 +753,19 @@ | |
| 753 | if( P("domod") ) return 1; |
| 754 | if( g.perm.WrTForum ) return 0; |
| 755 | if( g.perm.ModForum ) return 0; |
| 756 | return 1; |
| 757 | } |
| 758 | |
| 759 | /* |
| 760 | ** Add a new Forum Post artifact to the repository. |
| 761 | ** |
| 762 | ** Return true if a redirect occurs. |
| @@ -773,12 +782,16 @@ | |
| 773 | char *zI; |
| 774 | char *zG; |
| 775 | int iBasis; |
| 776 | Blob x, cksum, formatCheck, errMsg; |
| 777 | Manifest *pPost; |
| 778 | |
| 779 | schema_forum(); |
| 780 | if( iInReplyTo==0 && iEdit>0 ){ |
| 781 | iBasis = iEdit; |
| 782 | iInReplyTo = db_int(0, "SELECT firt FROM forumpost WHERE fpid=%d", iEdit); |
| 783 | }else{ |
| 784 | iBasis = iInReplyTo; |
| @@ -819,11 +832,11 @@ | |
| 819 | }else{ |
| 820 | zUser = login_name(); |
| 821 | } |
| 822 | } |
| 823 | blob_appendf(&x, "U %F\n", zUser); |
| 824 | blob_appendf(&x, "W %d\n%s\n", strlen(zContent), zContent); |
| 825 | md5sum_blob(&x, &cksum); |
| 826 | blob_appendf(&x, "Z %b\n", &cksum); |
| 827 | blob_reset(&cksum); |
| 828 | |
| 829 | /* Verify that the artifact we are creating is well-formed */ |
| @@ -953,21 +966,21 @@ | |
| 953 | return; |
| 954 | } |
| 955 | if( P("submit") && cgi_csrf_safe(1) ){ |
| 956 | if( forum_post(zTitle, 0, 0, 0, zMimetype, zContent) ) return; |
| 957 | } |
| 958 | if( P("preview") ){ |
| 959 | @ <h1>Preview:</h1> |
| 960 | forum_render(zTitle, zMimetype, zContent, "forumEdit", 1); |
| 961 | } |
| 962 | style_header("New Forum Thread"); |
| 963 | @ <form action="%R/forume1" method="POST"> |
| 964 | @ <h1>New Thread:</h1> |
| 965 | forum_from_line(); |
| 966 | forum_entry_widget(zTitle, zMimetype, zContent); |
| 967 | @ <input type="submit" name="preview" value="Preview"> |
| 968 | if( P("preview") ){ |
| 969 | @ <input type="submit" name="submit" value="Submit"> |
| 970 | }else{ |
| 971 | @ <input type="submit" name="submit" value="Submit" disabled> |
| 972 | } |
| 973 | if( g.perm.Debug ){ |
| @@ -1053,11 +1066,11 @@ | |
| 1053 | } |
| 1054 | return; |
| 1055 | } |
| 1056 | } |
| 1057 | isDelete = P("nullout")!=0; |
| 1058 | if( P("submit") && isCsrfSafe ){ |
| 1059 | int done = 1; |
| 1060 | const char *zMimetype = PD("mimetype",DEFAULT_FORUM_MIMETYPE); |
| 1061 | const char *zContent = PDT("content",""); |
| 1062 | if( P("reply") ){ |
| 1063 | done = forum_post(0, fpid, 0, 0, zMimetype, zContent); |
| @@ -1124,11 +1137,11 @@ | |
| 1124 | zDisplayName = display_name_from_login(pPost->zUser); |
| 1125 | @ <h3 class='forumPostHdr'>By %h(zDisplayName) on %h(zDate)</h3> |
| 1126 | fossil_free(zDisplayName); |
| 1127 | fossil_free(zDate); |
| 1128 | forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit", 1); |
| 1129 | if( P("preview") ){ |
| 1130 | @ <h2>Preview:</h2> |
| 1131 | forum_render(0, zMimetype,zContent, "forumEdit", 1); |
| 1132 | } |
| 1133 | @ <h2>Enter Reply:</h2> |
| 1134 | @ <form action="%R/forume2" method="POST"> |
| @@ -1139,11 +1152,11 @@ | |
| 1139 | } |
| 1140 | if( !isDelete ){ |
| 1141 | @ <input type="submit" name="preview" value="Preview"> |
| 1142 | } |
| 1143 | @ <input type="submit" name="cancel" value="Cancel"> |
| 1144 | if( P("preview") || isDelete ){ |
| 1145 | @ <input type="submit" name="submit" value="Submit"> |
| 1146 | } |
| 1147 | if( g.perm.Debug ){ |
| 1148 | /* For the test-forumnew page add these extra debugging controls */ |
| 1149 | @ <div class="debug"> |
| 1150 |
| --- src/forum.c | |
| +++ src/forum.c | |
| @@ -753,10 +753,19 @@ | |
| 753 | if( P("domod") ) return 1; |
| 754 | if( g.perm.WrTForum ) return 0; |
| 755 | if( g.perm.ModForum ) return 0; |
| 756 | return 1; |
| 757 | } |
| 758 | |
| 759 | /* |
| 760 | ** Return true if the string is white-space only. |
| 761 | */ |
| 762 | static int whitespace_only(const char *z){ |
| 763 | if( z==0 ) return 1; |
| 764 | while( z[0] && fossil_isspace(z[0]) ){ z++; } |
| 765 | return z[0]==0; |
| 766 | } |
| 767 | |
| 768 | /* |
| 769 | ** Add a new Forum Post artifact to the repository. |
| 770 | ** |
| 771 | ** Return true if a redirect occurs. |
| @@ -773,12 +782,16 @@ | |
| 782 | char *zI; |
| 783 | char *zG; |
| 784 | int iBasis; |
| 785 | Blob x, cksum, formatCheck, errMsg; |
| 786 | Manifest *pPost; |
| 787 | int nContent = zContent ? (int)strlen(zContent) : 0; |
| 788 | |
| 789 | schema_forum(); |
| 790 | if( iEdit==0 && whitespace_only(zContent) ){ |
| 791 | return 0; |
| 792 | } |
| 793 | if( iInReplyTo==0 && iEdit>0 ){ |
| 794 | iBasis = iEdit; |
| 795 | iInReplyTo = db_int(0, "SELECT firt FROM forumpost WHERE fpid=%d", iEdit); |
| 796 | }else{ |
| 797 | iBasis = iInReplyTo; |
| @@ -819,11 +832,11 @@ | |
| 832 | }else{ |
| 833 | zUser = login_name(); |
| 834 | } |
| 835 | } |
| 836 | blob_appendf(&x, "U %F\n", zUser); |
| 837 | blob_appendf(&x, "W %d\n%s\n", nContent, zContent); |
| 838 | md5sum_blob(&x, &cksum); |
| 839 | blob_appendf(&x, "Z %b\n", &cksum); |
| 840 | blob_reset(&cksum); |
| 841 | |
| 842 | /* Verify that the artifact we are creating is well-formed */ |
| @@ -953,21 +966,21 @@ | |
| 966 | return; |
| 967 | } |
| 968 | if( P("submit") && cgi_csrf_safe(1) ){ |
| 969 | if( forum_post(zTitle, 0, 0, 0, zMimetype, zContent) ) return; |
| 970 | } |
| 971 | if( P("preview") && !whitespace_only(zContent) ){ |
| 972 | @ <h1>Preview:</h1> |
| 973 | forum_render(zTitle, zMimetype, zContent, "forumEdit", 1); |
| 974 | } |
| 975 | style_header("New Forum Thread"); |
| 976 | @ <form action="%R/forume1" method="POST"> |
| 977 | @ <h1>New Thread:</h1> |
| 978 | forum_from_line(); |
| 979 | forum_entry_widget(zTitle, zMimetype, zContent); |
| 980 | @ <input type="submit" name="preview" value="Preview"> |
| 981 | if( P("preview") && !whitespace_only(zContent) ){ |
| 982 | @ <input type="submit" name="submit" value="Submit"> |
| 983 | }else{ |
| 984 | @ <input type="submit" name="submit" value="Submit" disabled> |
| 985 | } |
| 986 | if( g.perm.Debug ){ |
| @@ -1053,11 +1066,11 @@ | |
| 1066 | } |
| 1067 | return; |
| 1068 | } |
| 1069 | } |
| 1070 | isDelete = P("nullout")!=0; |
| 1071 | if( P("submit") && (isDelete || !whitespace_only(zContent)) && isCsrfSafe ){ |
| 1072 | int done = 1; |
| 1073 | const char *zMimetype = PD("mimetype",DEFAULT_FORUM_MIMETYPE); |
| 1074 | const char *zContent = PDT("content",""); |
| 1075 | if( P("reply") ){ |
| 1076 | done = forum_post(0, fpid, 0, 0, zMimetype, zContent); |
| @@ -1124,11 +1137,11 @@ | |
| 1137 | zDisplayName = display_name_from_login(pPost->zUser); |
| 1138 | @ <h3 class='forumPostHdr'>By %h(zDisplayName) on %h(zDate)</h3> |
| 1139 | fossil_free(zDisplayName); |
| 1140 | fossil_free(zDate); |
| 1141 | forum_render(0, pPost->zMimetype, pPost->zWiki, "forumEdit", 1); |
| 1142 | if( P("preview") && !whitespace_only(zContent) ){ |
| 1143 | @ <h2>Preview:</h2> |
| 1144 | forum_render(0, zMimetype,zContent, "forumEdit", 1); |
| 1145 | } |
| 1146 | @ <h2>Enter Reply:</h2> |
| 1147 | @ <form action="%R/forume2" method="POST"> |
| @@ -1139,11 +1152,11 @@ | |
| 1152 | } |
| 1153 | if( !isDelete ){ |
| 1154 | @ <input type="submit" name="preview" value="Preview"> |
| 1155 | } |
| 1156 | @ <input type="submit" name="cancel" value="Cancel"> |
| 1157 | if( (P("preview") && !whitespace_only(zContent)) || isDelete ){ |
| 1158 | @ <input type="submit" name="submit" value="Submit"> |
| 1159 | } |
| 1160 | if( g.perm.Debug ){ |
| 1161 | /* For the test-forumnew page add these extra debugging controls */ |
| 1162 | @ <div class="debug"> |
| 1163 |