Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Send the --from argument of the "fossil ui" command encoded as hexadecimal, to work around quoting problems on Windows. [forum:/forumpost/cfc22d41b19a1a96|Forum post cfc22d41b19a1a96]. |
|---|---|
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
593ceca27dbe17d8d7658c217a771792 |
| User & Date: | drh 2024-12-17 12:38:33.468 |
References
|
2024-12-18
| ||
| 18:30 | Fix a problem introduced with [593ceca27d]: the blob resize operation may realloc the buffer, so obtain the pointer to the buffer only after the resize to avoid a "use after free". check-in: 36bcaaeee0 user: florian tags: trunk | |
Context
|
2024-12-18
| ||
| 05:06 | Call `cgi_is_loopback()' before `db_open_local()' when checking for a local `fossil ui' session. The former performs simple string comparison, while the latter crawls the file system for multiple (3) check-out database file names at multiple directory hierarchy levels. The main motivation for this change is to reduce "attack surface" of the /jchunk... check-in: 2dda151c40 user: florian tags: trunk | |
|
2024-12-17
| ||
| 12:38 | Send the --from argument of the "fossil ui" command encoded as hexadecimal, to work around quoting problems on Windows. [forum:/forumpost/cfc22d41b19a1a96|Forum post cfc22d41b19a1a96]. check-in: 593ceca27d user: drh tags: trunk | |
| 06:12 | On the new /ckout UI page, output the page footer only once. check-in: 92372ce946 user: florian tags: trunk | |
Changes
Changes to src/encode.c.
| ︙ | ︙ | |||
727 728 729 730 731 732 733 734 735 736 737 738 739 740 |
*/
void canonical16(char *z, int n){
while( *z && n-- ){
*z = zEncode[zDecode[(*z)&0x7f]&0x1f];
z++;
}
}
/*
** Decode a string encoded using "quoted-printable".
**
** (1) "=" followed by two hex digits becomes a single
** byte specified by the two digits
**
| > > > > > > > > > > > > > > > > > > | 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
*/
void canonical16(char *z, int n){
while( *z && n-- ){
*z = zEncode[zDecode[(*z)&0x7f]&0x1f];
z++;
}
}
/*
** Decode hexadecimal into a string and return the new string. Space to
** hold the string is obtained from fossil_malloc() and should be released
** by the caller.
**
** If the input is not hex, return NULL.
*/
char *decode16_dup(const char *zIn){
int nIn = (int)strlen(zIn);
char *zOut;
if( !validate16(zIn, nIn) ) return 0;
zOut = fossil_malloc(nIn/2+1);
decode16((const u8*)zIn, (u8*)zOut, nIn);
zOut[nIn/2] = 0;
return zOut;
}
/*
** Decode a string encoded using "quoted-printable".
**
** (1) "=" followed by two hex digits becomes a single
** byte specified by the two digits
**
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
782 783 784 785 786 787 788 |
){
@ <div class='file-change-line'><span>
@ Changes to %h(zFile)
@ </span></div>
if( pCfg ){
char *zFullFN;
char *zHexFN;
| < < | < < < | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 |
){
@ <div class='file-change-line'><span>
@ Changes to %h(zFile)
@ </span></div>
if( pCfg ){
char *zFullFN;
char *zHexFN;
zFullFN = file_canonical_name_dup(zLhs);
zHexFN = mprintf("x%H", zFullFN);
fossil_free(zFullFN);
pCfg->zLeftHash = zHexFN;
text_diff(&lhs, &rhs, cgi_output_blob(), pCfg);
pCfg->zLeftHash = 0;
fossil_free(zHexFN);
}
}
|
| ︙ | ︙ | |||
817 818 819 820 821 822 823 | ** if the web server is run on a loopback interface (in other words, was ** started using "fossil ui" or similar) from within an open check-out. ** ** If the "exbase=PATH" query parameter is provided, then the diff shown ** uses the files in PATH as the baseline. This is the same as using ** the "--from PATH" argument to the "fossil diff" command-line. In fact, ** when using "fossil ui --from PATH", the --from argument becomes the value | | > > > | 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 |
** if the web server is run on a loopback interface (in other words, was
** started using "fossil ui" or similar) from within an open check-out.
**
** If the "exbase=PATH" query parameter is provided, then the diff shown
** uses the files in PATH as the baseline. This is the same as using
** the "--from PATH" argument to the "fossil diff" command-line. In fact,
** when using "fossil ui --from PATH", the --from argument becomes the value
** of the exbase query parameter for the start page. Note that if PATH
** is a pure hexadecimal string, it is decoded first before being used as
** the pathname. Real pathnames should contain at least one directory
** separator character.
**
** Other query parameters related to diffs are also accepted.
*/
void ckout_page(void){
int vid;
const char *zHome; /* Home directory */
int nHome;
|
| ︙ | ︙ | |||
859 860 861 862 863 864 865 |
}else{
style_header("Checkout Status: %h", zCwd);
}
render_checkin_context(vid, 0, 0, 0);
@ <hr>
zExBase = P("exbase");
if( zExBase && zExBase[0] ){
| > | > | 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 |
}else{
style_header("Checkout Status: %h", zCwd);
}
render_checkin_context(vid, 0, 0, 0);
@ <hr>
zExBase = P("exbase");
if( zExBase && zExBase[0] ){
char *zPath = decode16_dup(zExBase);
char *zCBase = file_canonical_name_dup(zPath?zPath:zExBase);
if( nHome && strncmp(zCBase, zHome, nHome)==0 && zCBase[nHome]=='/' ){
@ <p>Using external baseline: ~%h(zCBase+nHome)</p>
}else{
@ <p>Using external baseline: %h(zCBase)</p>
}
ckout_external_base_diff(vid, zCBase);
fossil_free(zCBase);
fossil_free(zPath);
}else{
ckout_normal_diff(vid);
}
style_finish_page();
}
/*
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
3295 3296 3297 3298 3299 3300 3301 |
fossil_fatal("the argument to --from must be a pathname for"
" the \"ui\" command");
}
zInitPage = find_option("page", "p", 1);
if( zInitPage && zInitPage[0]=='/' ) zInitPage++;
zFossilCmd = find_option("fossilcmd", 0, 1);
if( zFrom && zInitPage==0 ){
| | | 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 |
fossil_fatal("the argument to --from must be a pathname for"
" the \"ui\" command");
}
zInitPage = find_option("page", "p", 1);
if( zInitPage && zInitPage[0]=='/' ) zInitPage++;
zFossilCmd = find_option("fossilcmd", 0, 1);
if( zFrom && zInitPage==0 ){
zInitPage = mprintf("ckout?exbase=%H", zFrom);
}
}
zNotFound = find_option("notfound", 0, 1);
allowRepoList = find_option("repolist",0,0)!=0;
if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
zAltBase = find_option("baseurl", 0, 1);
fCreate = find_option("create",0,0)!=0;
|
| ︙ | ︙ |
Changes to src/printf.c.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
#define etROOT 24 /* String value of g.zTop: %R */
#define etJSONSTR 25 /* String encoded as a JSON string literal: %j
Use %!j to include double-quotes around it. */
#define etSHELLESC 26 /* Escape a filename for use in a shell command: %$
See blob_append_escaped_arg() for details
"%$" -> adds "./" prefix if necessary.
"%!$" -> omits the "./" prefix. */
/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;
| > | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
#define etROOT 24 /* String value of g.zTop: %R */
#define etJSONSTR 25 /* String encoded as a JSON string literal: %j
Use %!j to include double-quotes around it. */
#define etSHELLESC 26 /* Escape a filename for use in a shell command: %$
See blob_append_escaped_arg() for details
"%$" -> adds "./" prefix if necessary.
"%!$" -> omits the "./" prefix. */
#define etHEX 27 /* Encode a string as hexadecimal */
/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;
|
| ︙ | ︙ | |||
140 141 142 143 144 145 146 | ** most frequently used conversion types first. ** ** NB: When modifying this table is it vital that you also update the fmtchr[] ** variable to match!!! */ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; | | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
** most frequently used conversion types first.
**
** NB: When modifying this table is it vital that you also update the fmtchr[]
** variable to match!!!
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const char fmtchr[] = "dsgzqQbBWhRtTwFSjcouxXfeEGin%p/$H";
static const et_info fmtinfo[] = {
{ 'd', 10, 1, etRADIX, 0, 0 },
{ 's', 0, 4, etSTRING, 0, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'z', 0, 6, etDYNSTRING, 0, 0 },
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
|
| ︙ | ︙ | |||
174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
{ 'G', 0, 1, etGENERIC, 14, 0 },
{ 'i', 10, 1, etRADIX, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
{ '/', 0, 0, etPATH, 0, 0 },
{ '$', 0, 0, etSHELLESC, 0, 0 },
{ etERROR, 0,0,0,0,0} /* Must be last */
};
#define etNINFO count(fmtinfo)
/*
** Verify that the fmtchr[] and fmtinfo[] arrays are in agreement.
**
| > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
{ 'G', 0, 1, etGENERIC, 14, 0 },
{ 'i', 10, 1, etRADIX, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
{ '/', 0, 0, etPATH, 0, 0 },
{ '$', 0, 0, etSHELLESC, 0, 0 },
{ 'H', 0, 0, etHEX, 0, 0 },
{ etERROR, 0,0,0,0,0} /* Must be last */
};
#define etNINFO count(fmtinfo)
/*
** Verify that the fmtchr[] and fmtinfo[] arrays are in agreement.
**
|
| ︙ | ︙ | |||
841 842 843 844 845 846 847 848 849 850 851 852 853 854 |
break;
}
case etSHELLESC: {
char *zArg = va_arg(ap, char*);
blob_append_escaped_arg(pBlob, zArg, !flag_altform2);
length = width = 0;
break;
}
case etERROR:
buf[0] = '%';
buf[1] = c;
errorflag = 0;
idx = 1+(c!=0);
blob_append(pBlob,"%",idx);
| > > > > > > > > > > | 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 |
break;
}
case etSHELLESC: {
char *zArg = va_arg(ap, char*);
blob_append_escaped_arg(pBlob, zArg, !flag_altform2);
length = width = 0;
break;
}
case etHEX: {
char *zArg = va_arg(ap, char*);
int szArg = (int)strlen(zArg);
int szBlob = blob_size(pBlob);
u8 *aBuf = (u8*)&blob_buffer(pBlob)[szBlob];
blob_resize(pBlob, szBlob+szArg*2+1);
encode16((const u8*)zArg, aBuf, szArg);
length = width = 0;
break;
}
case etERROR:
buf[0] = '%';
buf[1] = c;
errorflag = 0;
idx = 1+(c!=0);
blob_append(pBlob,"%",idx);
|
| ︙ | ︙ |