Fossil SCM
/chat: when downloading a file via chat which has a text/... mimetype but it looks_like_binary(), change the mimetype to application/octet-stream. See code comments for the motivation behind this.
Commit
87edfb0a48fc4643a4bd664f3f73c2e5599d43901b77657063ad73f3407601e5
Parent
764c50aeff3cf7f…
1 file changed
+21
-2
+21
-2
| --- src/chat.c | ||
| +++ src/chat.c | ||
| @@ -942,12 +942,14 @@ | ||
| 942 | 942 | ** image/svg+xml if rendering succeeds or text/html if rendering |
| 943 | 943 | ** fails. |
| 944 | 944 | */ |
| 945 | 945 | void chat_download_webpage(void){ |
| 946 | 946 | int msgid; |
| 947 | - Blob r; | |
| 948 | - const char *zMime; | |
| 947 | + int bCheckedMimetype = 0; /* true to bypass the text/... mimetype | |
| 948 | + ** check at the end */ | |
| 949 | + Blob r; /* file content */ | |
| 950 | + const char *zMime; /* file mimetype */ | |
| 949 | 951 | const char *zName = PD("name","0"); |
| 950 | 952 | login_check_credentials(); |
| 951 | 953 | if( !g.perm.Chat ){ |
| 952 | 954 | style_header("Chat Not Authorized"); |
| 953 | 955 | @ <h1>Not Authorized</h1> |
| @@ -970,15 +972,17 @@ | ||
| 970 | 972 | /* Firefox uploads md files with the mimetype text/markdown */ |
| 971 | 973 | || fossil_strcmp(zMime, "text/markdown")==0){ |
| 972 | 974 | markdown_to_html(&r, 0, &r2); |
| 973 | 975 | safe_html(&r2); |
| 974 | 976 | zMime2 = "text/html"; |
| 977 | + bCheckedMimetype = 1; | |
| 975 | 978 | }else if(fossil_strcmp(zMime, "text/x-fossil-wiki")==0 |
| 976 | 979 | || sqlite3_strglob("*.wiki", zName)==0){ |
| 977 | 980 | /* .wiki files get uploaded as application/octet-stream */ |
| 978 | 981 | wiki_convert(&r, &r2, 0); |
| 979 | 982 | zMime2 = "text/html"; |
| 983 | + bCheckedMimetype = 1; | |
| 980 | 984 | }else if(fossil_strcmp(zMime, "text/x-pikchr")==0 |
| 981 | 985 | || sqlite3_strglob("*.pikchr",zName)==0){ |
| 982 | 986 | /* .pikchr files get uploaded as application/octet-stream */ |
| 983 | 987 | const char *zPikchr = blob_str(&r); |
| 984 | 988 | int w = 0, h = 0; |
| @@ -986,16 +990,31 @@ | ||
| 986 | 990 | if(zOut){ |
| 987 | 991 | blob_append(&r2, zOut, -1); |
| 988 | 992 | } |
| 989 | 993 | zMime2 = w>0 ? "image/svg+xml" : "text/html"; |
| 990 | 994 | free(zOut); |
| 995 | + bCheckedMimetype = 1; | |
| 991 | 996 | } |
| 992 | 997 | if(r2.aData!=0){ |
| 993 | 998 | blob_swap(&r, &r2); |
| 994 | 999 | blob_reset(&r2); |
| 995 | 1000 | zMime = zMime2; |
| 996 | 1001 | } |
| 1002 | + } | |
| 1003 | + if( bCheckedMimetype==0 && sqlite3_strglob("text/*", zMime)==0 ){ | |
| 1004 | + /* The problem: both Chrome and Firefox upload *.patch with | |
| 1005 | + ** the mimetype text/x-patch, whereas we very often use that | |
| 1006 | + ** name glob for fossil-format patches. That causes such files | |
| 1007 | + ** to attempt to render in the browser when clicked via | |
| 1008 | + ** download links in chat. | |
| 1009 | + ** | |
| 1010 | + ** The workaround: if a text/... file is looks_like_binary() | |
| 1011 | + ** then change the mimetype to application/octet-stream. | |
| 1012 | + */ | |
| 1013 | + if( looks_like_binary(&r) ){ | |
| 1014 | + zMime = "application/octet-stream"; | |
| 1015 | + } | |
| 997 | 1016 | } |
| 998 | 1017 | cgi_set_content_type(zMime); |
| 999 | 1018 | cgi_set_content(&r); |
| 1000 | 1019 | } |
| 1001 | 1020 | |
| 1002 | 1021 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -942,12 +942,14 @@ | |
| 942 | ** image/svg+xml if rendering succeeds or text/html if rendering |
| 943 | ** fails. |
| 944 | */ |
| 945 | void chat_download_webpage(void){ |
| 946 | int msgid; |
| 947 | Blob r; |
| 948 | const char *zMime; |
| 949 | const char *zName = PD("name","0"); |
| 950 | login_check_credentials(); |
| 951 | if( !g.perm.Chat ){ |
| 952 | style_header("Chat Not Authorized"); |
| 953 | @ <h1>Not Authorized</h1> |
| @@ -970,15 +972,17 @@ | |
| 970 | /* Firefox uploads md files with the mimetype text/markdown */ |
| 971 | || fossil_strcmp(zMime, "text/markdown")==0){ |
| 972 | markdown_to_html(&r, 0, &r2); |
| 973 | safe_html(&r2); |
| 974 | zMime2 = "text/html"; |
| 975 | }else if(fossil_strcmp(zMime, "text/x-fossil-wiki")==0 |
| 976 | || sqlite3_strglob("*.wiki", zName)==0){ |
| 977 | /* .wiki files get uploaded as application/octet-stream */ |
| 978 | wiki_convert(&r, &r2, 0); |
| 979 | zMime2 = "text/html"; |
| 980 | }else if(fossil_strcmp(zMime, "text/x-pikchr")==0 |
| 981 | || sqlite3_strglob("*.pikchr",zName)==0){ |
| 982 | /* .pikchr files get uploaded as application/octet-stream */ |
| 983 | const char *zPikchr = blob_str(&r); |
| 984 | int w = 0, h = 0; |
| @@ -986,16 +990,31 @@ | |
| 986 | if(zOut){ |
| 987 | blob_append(&r2, zOut, -1); |
| 988 | } |
| 989 | zMime2 = w>0 ? "image/svg+xml" : "text/html"; |
| 990 | free(zOut); |
| 991 | } |
| 992 | if(r2.aData!=0){ |
| 993 | blob_swap(&r, &r2); |
| 994 | blob_reset(&r2); |
| 995 | zMime = zMime2; |
| 996 | } |
| 997 | } |
| 998 | cgi_set_content_type(zMime); |
| 999 | cgi_set_content(&r); |
| 1000 | } |
| 1001 | |
| 1002 |
| --- src/chat.c | |
| +++ src/chat.c | |
| @@ -942,12 +942,14 @@ | |
| 942 | ** image/svg+xml if rendering succeeds or text/html if rendering |
| 943 | ** fails. |
| 944 | */ |
| 945 | void chat_download_webpage(void){ |
| 946 | int msgid; |
| 947 | int bCheckedMimetype = 0; /* true to bypass the text/... mimetype |
| 948 | ** check at the end */ |
| 949 | Blob r; /* file content */ |
| 950 | const char *zMime; /* file mimetype */ |
| 951 | const char *zName = PD("name","0"); |
| 952 | login_check_credentials(); |
| 953 | if( !g.perm.Chat ){ |
| 954 | style_header("Chat Not Authorized"); |
| 955 | @ <h1>Not Authorized</h1> |
| @@ -970,15 +972,17 @@ | |
| 972 | /* Firefox uploads md files with the mimetype text/markdown */ |
| 973 | || fossil_strcmp(zMime, "text/markdown")==0){ |
| 974 | markdown_to_html(&r, 0, &r2); |
| 975 | safe_html(&r2); |
| 976 | zMime2 = "text/html"; |
| 977 | bCheckedMimetype = 1; |
| 978 | }else if(fossil_strcmp(zMime, "text/x-fossil-wiki")==0 |
| 979 | || sqlite3_strglob("*.wiki", zName)==0){ |
| 980 | /* .wiki files get uploaded as application/octet-stream */ |
| 981 | wiki_convert(&r, &r2, 0); |
| 982 | zMime2 = "text/html"; |
| 983 | bCheckedMimetype = 1; |
| 984 | }else if(fossil_strcmp(zMime, "text/x-pikchr")==0 |
| 985 | || sqlite3_strglob("*.pikchr",zName)==0){ |
| 986 | /* .pikchr files get uploaded as application/octet-stream */ |
| 987 | const char *zPikchr = blob_str(&r); |
| 988 | int w = 0, h = 0; |
| @@ -986,16 +990,31 @@ | |
| 990 | if(zOut){ |
| 991 | blob_append(&r2, zOut, -1); |
| 992 | } |
| 993 | zMime2 = w>0 ? "image/svg+xml" : "text/html"; |
| 994 | free(zOut); |
| 995 | bCheckedMimetype = 1; |
| 996 | } |
| 997 | if(r2.aData!=0){ |
| 998 | blob_swap(&r, &r2); |
| 999 | blob_reset(&r2); |
| 1000 | zMime = zMime2; |
| 1001 | } |
| 1002 | } |
| 1003 | if( bCheckedMimetype==0 && sqlite3_strglob("text/*", zMime)==0 ){ |
| 1004 | /* The problem: both Chrome and Firefox upload *.patch with |
| 1005 | ** the mimetype text/x-patch, whereas we very often use that |
| 1006 | ** name glob for fossil-format patches. That causes such files |
| 1007 | ** to attempt to render in the browser when clicked via |
| 1008 | ** download links in chat. |
| 1009 | ** |
| 1010 | ** The workaround: if a text/... file is looks_like_binary() |
| 1011 | ** then change the mimetype to application/octet-stream. |
| 1012 | */ |
| 1013 | if( looks_like_binary(&r) ){ |
| 1014 | zMime = "application/octet-stream"; |
| 1015 | } |
| 1016 | } |
| 1017 | cgi_set_content_type(zMime); |
| 1018 | cgi_set_content(&r); |
| 1019 | } |
| 1020 | |
| 1021 |