Fossil

Check-in [7ed9c7e4]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Sanitize the mimetypes on both the CLI and json. Allow more friendly names for the supported mimetypes as well as the formal mimetypes
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | technoteattachcli
Files: files | file ages | folders
SHA1:7ed9c7e4a9eae1d8fec14fb33e6b01f9ebaa97f2
User & Date: dave.vines 2016-04-18 19:18:19
Context
2016-05-03
07:11
Move loop variable declaration out of for loop for C89 happiness. check-in: 5a0dbf97 user: rberteig tags: technoteattachcli
2016-04-18
19:18
Sanitize the mimetypes on both the CLI and json. Allow more friendly names for the supported mimetypes as well as the formal mimetypes check-in: 7ed9c7e4 user: dave.vines tags: technoteattachcli
13:36
add TECHNOTEID to fossil attach command check-in: 70131d08 user: dave.vines tags: technoteattachcli
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/json_wiki.c.

372
373
374
375
376
377
378

379
380
381
382
383
384
385
  jstr = cson_value_get_string(contentV);
  contentLen = (int)cson_string_length_bytes(jstr);
  if(contentLen){
    blob_append(&content, cson_string_cstr(jstr),contentLen);
  }

  zMimeType = json_find_option_cstr("mimetype","mimetype","M");


  wiki_cmd_commit(zPageName, rid, &content, zMimeType, 0);
  blob_reset(&content);
  /*
    Our return value here has a race condition: if this operation
    is called concurrently for the same wiki page via two requests,
    payV could reflect the results of the other save operation.







>







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
  jstr = cson_value_get_string(contentV);
  contentLen = (int)cson_string_length_bytes(jstr);
  if(contentLen){
    blob_append(&content, cson_string_cstr(jstr),contentLen);
  }

  zMimeType = json_find_option_cstr("mimetype","mimetype","M");
  zMimeType = wiki_filter_mimetypes(zMimeType);

  wiki_cmd_commit(zPageName, rid, &content, zMimeType, 0);
  blob_reset(&content);
  /*
    Our return value here has a race condition: if this operation
    is called concurrently for the same wiki page via two requests,
    payV could reflect the results of the other save operation.

Changes to src/wiki.c.

120
121
122
123
124
125
126









127
128
129
130
131
132





133
134
135
136

137
138
139
140
141
142
143
...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
....
1312
1313
1314
1315
1316
1317
1318


1319
1320
1321
1322
1323
1324
1325
** Return true if the given pagename is the name of the sandbox
*/
static int is_sandbox(const char *zPagename){
  return fossil_stricmp(zPagename,"sandbox")==0 ||
         fossil_stricmp(zPagename,"sand box")==0;
}










/*
** Only allow certain mimetypes through.
** All others become "text/x-fossil-wiki"
*/
const char *wiki_filter_mimetypes(const char *zMimetype){
  if( zMimetype!=0 &&





      ( fossil_strcmp(zMimetype, "text/x-markdown")==0
        || fossil_strcmp(zMimetype, "text/plain")==0 )
  ){
    return zMimetype;

  }
  return "text/x-fossil-wiki";
}

/*
** Render wiki text according to its mimetype.
**
................................................................................
    db_multi_exec("INSERT INTO modreq(objid) VALUES(%d)", nrid);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
  db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", nrid);
  manifest_crosslink(nrid, pWiki, MC_NONE);
}

/*
** Formal names and common names for the various wiki styles.
*/
static const char *const azStyles[] = {
  "text/x-fossil-wiki", "Fossil Wiki",
  "text/x-markdown",    "Markdown",
  "text/plain",         "Plain Text"
};

/*
** Output a selection box from which the user can select the
** wiki mimetype.
*/
void mimetype_option_menu(const char *zMimetype){
  unsigned i;
  @ <select name="mimetype" size="1">
  for(i=0; i<sizeof(azStyles)/sizeof(azStyles[0]); i+=2){
    if( fossil_strcmp(zMimetype,azStyles[i])==0 ){
      @ <option value="%s(azStyles[i])" selected>%s(azStyles[i+1])</option>
    }else{
      @ <option value="%s(azStyles[i])">%s(azStyles[i+1])</option>
    }
  }
  @ </select>
................................................................................
      }else{
        rid = wiki_technote_to_rid(zETime);
        if(rid>0 && (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0
           && (pWiki->zMimetype && *pWiki->zMimetype)){
          zMimeType = pWiki->zMimetype;
        }
      }


    }
    if( g.argv[2][1]=='r' && rid>0 ){
      if ( !zETime ){
        fossil_fatal("wiki page %s already exists", zPageName);
      }else{
        /* Creating a tech note with same timestamp is permitted
           and should create a new tech note */







>
>
>
>
>
>
>
>
>





|
>
>
>
>
>
|
|
<
|
>







 







<
<
<
<
<
<
<
<
<







|







 







>
>







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
156
157
...
424
425
426
427
428
429
430









431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
....
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
** Return true if the given pagename is the name of the sandbox
*/
static int is_sandbox(const char *zPagename){
  return fossil_stricmp(zPagename,"sandbox")==0 ||
         fossil_stricmp(zPagename,"sand box")==0;
}

/*
** Formal, common and short names for the various wiki styles.
*/
static const char *const azStyles[] = {
  "text/x-fossil-wiki", "Fossil Wiki", "wiki",
  "text/x-markdown",    "Markdown",    "markdown",
  "text/plain",         "Plain Text",  "plain"
};

/*
** Only allow certain mimetypes through.
** All others become "text/x-fossil-wiki"
*/
const char *wiki_filter_mimetypes(const char *zMimetype){
  if( zMimetype!=0 ){
    for(int i=0; i<sizeof(azStyles)/sizeof(azStyles[0]); i+=3){
      if( fossil_strcmp(zMimetype,azStyles[i+2])==0 ){
        return azStyles[i];
      }
    }
    if(  fossil_strcmp(zMimetype, "text/x-markdown")==0
        || fossil_strcmp(zMimetype, "text/plain")==0 ){

      return zMimetype;
    }
  }
  return "text/x-fossil-wiki";
}

/*
** Render wiki text according to its mimetype.
**
................................................................................
    db_multi_exec("INSERT INTO modreq(objid) VALUES(%d)", nrid);
  }
  db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
  db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d);", nrid);
  manifest_crosslink(nrid, pWiki, MC_NONE);
}










/*
** Output a selection box from which the user can select the
** wiki mimetype.
*/
void mimetype_option_menu(const char *zMimetype){
  unsigned i;
  @ <select name="mimetype" size="1">
  for(i=0; i<sizeof(azStyles)/sizeof(azStyles[0]); i+=3){
    if( fossil_strcmp(zMimetype,azStyles[i])==0 ){
      @ <option value="%s(azStyles[i])" selected>%s(azStyles[i+1])</option>
    }else{
      @ <option value="%s(azStyles[i])">%s(azStyles[i+1])</option>
    }
  }
  @ </select>
................................................................................
      }else{
        rid = wiki_technote_to_rid(zETime);
        if(rid>0 && (pWiki = manifest_get(rid, CFTYPE_EVENT, 0))!=0
           && (pWiki->zMimetype && *pWiki->zMimetype)){
          zMimeType = pWiki->zMimetype;
        }
      }
    }else{
      zMimeType = wiki_filter_mimetypes(zMimeType);
    }
    if( g.argv[2][1]=='r' && rid>0 ){
      if ( !zETime ){
        fossil_fatal("wiki page %s already exists", zPageName);
      }else{
        /* Creating a tech note with same timestamp is permitted
           and should create a new tech note */