Fossil

Check-in [2cccc12d04]
Login

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

Overview
Comment:Added %!j to %j, which means to include double quotes around the resulting JSON string, and added the corresponding flag to encode_json_string_literal().
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | fileedit-ajaxify
Files: files | file ages | folders
SHA3-256: 2cccc12d0482cc137c30c4fea92fb69fc1eb62914cc8a0f2cc6d1f2921713335
User & Date: stephan 2020-05-15 03:34:25.338
Original Comment: Added %jobs to %j, which means to include double quotes around the resulting JSON string, and added the corresponding flag to encode_json_string_literal().
Context
2020-05-15
03:35
Cleaned up some JSON output using the new %!j format. check-in: d9fffa4c58 user: stephan tags: fileedit-ajaxify
03:34
Added %!j to %j, which means to include double quotes around the resulting JSON string, and added the corresponding flag to encode_json_string_literal(). check-in: 2cccc12d04 user: stephan tags: fileedit-ajaxify
02:39
Fixed multi-line commit comment (was not being submitted with commit) and change page title to reflect the file being edited, both per forum feedback. check-in: ef2166a0ac user: stephan tags: fileedit-ajaxify
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/encode.c.
375
376
377
378
379
380
381
382

383
384

385
386
387
388
389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408



409
410
411
412
413



414
415
416
417
418
419
420
        || (c&0xFFFFF800)==0xD800
        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }
  }
  return c;
}

/*
** Encode a UTF8 string as a JSON string literal (without the surrounding

** "...") and return a pointer to the encoding.  Space to hold the encoding
** is obtained from fossil_malloc() and must be freed by the caller.

**
** If nOut is not NULL then it is assigned to the length, in bytes, of
** the returned string (its strlen(), not counting the terminating
** NUL).
*/
char *encode_json_string_literal(const char *zStr, int * nOut){

  const unsigned char *z;
  char *zOut;
  u32 c;
  int n, i, j;
  z = (const unsigned char*)zStr;
  n = 0;
  while( (c = fossil_utf8_read(&z))!=0 ){
    if( c=='\\' || c=='"' ){
      n += 2;
    }else if( c<' ' || c>=0x7f ){
      if( c=='\n' || c=='\r' ){
        n += 2;
      }else{
        n += 6;
      }
    }else{
      n++;
    }



  }
  zOut = fossil_malloc(n+1);
  if( zOut==0 ) return 0;
  z = (const unsigned char*)zStr;
  i = 0;



  while( (c = fossil_utf8_read(&z))!=0 ){
    if( c=='\\' ){
      zOut[i++] = '\\';
      zOut[i++] = c;
    }else if( c<' ' || c>=0x7f ){
      zOut[i++] = '\\';
      if( c=='\n' ){







|
>
|
|
>





|
>


















>
>
>





>
>
>







375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
        || (c&0xFFFFF800)==0xD800
        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }
  }
  return c;
}

/*
** Encode a UTF8 string as a JSON string literal (with or without the
** surrounding "...", depending on whether the 2nd argument is true or
** false) and return a pointer to the encoding.  Space to hold the
** encoding is obtained from fossil_malloc() and must be freed by the
** caller.
**
** If nOut is not NULL then it is assigned to the length, in bytes, of
** the returned string (its strlen(), not counting the terminating
** NUL).
*/
char *encode_json_string_literal(const char *zStr, int fAddQuotes,
                                 int * nOut){
  const unsigned char *z;
  char *zOut;
  u32 c;
  int n, i, j;
  z = (const unsigned char*)zStr;
  n = 0;
  while( (c = fossil_utf8_read(&z))!=0 ){
    if( c=='\\' || c=='"' ){
      n += 2;
    }else if( c<' ' || c>=0x7f ){
      if( c=='\n' || c=='\r' ){
        n += 2;
      }else{
        n += 6;
      }
    }else{
      n++;
    }
  }
  if(fAddQuotes){
    n += 2;
  }
  zOut = fossil_malloc(n+1);
  if( zOut==0 ) return 0;
  z = (const unsigned char*)zStr;
  i = 0;
  if(fAddQuotes){
    zOut[i++] = '"';
  }
  while( (c = fossil_utf8_read(&z))!=0 ){
    if( c=='\\' ){
      zOut[i++] = '\\';
      zOut[i++] = c;
    }else if( c<' ' || c>=0x7f ){
      zOut[i++] = '\\';
      if( c=='\n' ){
429
430
431
432
433
434
435



436
437
438
439
440
441
442
        }
        i += 4;
      }
    }else{
      zOut[i++] = c;
    }
  }



  zOut[i] = 0;
  if(nOut!=0){
    *nOut = i;
  }
  return zOut;
}








>
>
>







438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
        }
        i += 4;
      }
    }else{
      zOut[i++] = c;
    }
  }
  if(fAddQuotes){
    zOut[i++] = '"';
  }
  zOut[i] = 0;
  if(nOut!=0){
    *nOut = i;
  }
  return zOut;
}

Changes to src/printf.c.
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
#define etHTTPIZE    18 /* Make text safe for HTTP.  "/" encoded as %2f */
#define etURLIZE     19 /* Make text safe for HTTP.  "/" not encoded */
#define etFOSSILIZE  20 /* The fossil header encoding format. */
#define etPATH       21 /* Path type */
#define etWIKISTR    22 /* Timeline comment text rendered from a char*: %W */
#define etSTRINGID   23 /* String with length limit for a UUID prefix: %S */
#define etROOT       24 /* String value of g.zTop: %R */
#define etJSONSTR    25 /* String encoded as a JSON string literal: %j */



/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;








|
>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#define etHTTPIZE    18 /* Make text safe for HTTP.  "/" encoded as %2f */
#define etURLIZE     19 /* Make text safe for HTTP.  "/" not encoded */
#define etFOSSILIZE  20 /* The fossil header encoding format. */
#define etPATH       21 /* Path type */
#define etWIKISTR    22 /* Timeline comment text rendered from a char*: %W */
#define etSTRINGID   23 /* String with length limit for a UUID prefix: %S */
#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. */


/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;

796
797
798
799
800
801
802
803

804
805
806
807
808
809
810
        char *zMem = va_arg(ap,char*);
        if( limit!=0 ){
          /* Ignore the limit flag, if set, for JSON string
          ** output. This block exists to squelch the associated
          ** "unused variable" compiler warning. */
        }
        if( zMem==0 ) zMem = "";
        zExtra = bufpt = encode_json_string_literal(zMem, &length);

        if( precision>=0 && precision<length ) length = precision;
        break;
      }
      case etWIKISTR: {
        int limit = flag_alternateform ? va_arg(ap,int) : -1;
        char *zWiki = va_arg(ap, char*);
        Blob wiki;







|
>







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
        char *zMem = va_arg(ap,char*);
        if( limit!=0 ){
          /* Ignore the limit flag, if set, for JSON string
          ** output. This block exists to squelch the associated
          ** "unused variable" compiler warning. */
        }
        if( zMem==0 ) zMem = "";
        zExtra = bufpt =
          encode_json_string_literal(zMem, flag_altform2, &length);
        if( precision>=0 && precision<length ) length = precision;
        break;
      }
      case etWIKISTR: {
        int limit = flag_alternateform ? va_arg(ap,int) : -1;
        char *zWiki = va_arg(ap, char*);
        Blob wiki;