~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/charset.c

  • Committer: Monty Taylor
  • Date: 2008-09-14 00:14:42 UTC
  • mto: This revision was merged to the branch mainline in revision 387.
  • Revision ID: monty@inaugust.com-20080914001442-09k3yuht4gopk0t6
Reworked drizzle_escape_string.

Show diffs side-by-side

added added

removed removed

Lines of Context:
404
404
}
405
405
 
406
406
 
407
 
/*
408
 
  Escape string with backslashes (\)
409
 
 
410
 
  SYNOPSIS
411
 
    escape_string_for_drizzle()
412
 
    charset_info        Charset of the strings
413
 
    to                  Buffer for escaped string
414
 
    to_length           Length of destination buffer, or 0
415
 
    from                The string to escape
416
 
    length              The length of the string to escape
417
 
 
418
 
  DESCRIPTION
419
 
    This escapes the contents of a string by adding backslashes before special
420
 
    characters, and turning others into specific escape sequences, such as
421
 
    turning newlines into \n and null bytes into \0.
422
 
 
423
 
  NOTE
424
 
    To maintain compatibility with the old C API, to_length may be 0 to mean
425
 
    "big enough"
426
 
 
427
 
  RETURN VALUES
428
 
    (size_t) -1 The escaped string did not fit in the to buffer
429
 
    #           The length of the escaped string
430
 
*/
431
 
 
432
 
size_t escape_string_for_drizzle(const CHARSET_INFO *charset_info,
433
 
                                 char *to, size_t to_length,
434
 
                                 const char *from, size_t length)
435
 
{
436
 
  const char *to_start= to;
437
 
  const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
438
 
  bool overflow= false;
439
 
#ifdef USE_MB
440
 
  bool use_mb_flag= use_mb(charset_info);
441
 
#endif
442
 
  for (end= from + length; from < end; from++)
443
 
  {
444
 
    char escape= 0;
445
 
#ifdef USE_MB
446
 
    int tmp_length;
447
 
    if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
448
 
    {
449
 
      if (to + tmp_length > to_end)
450
 
      {
451
 
        overflow= true;
452
 
        break;
453
 
      }
454
 
      while (tmp_length--)
455
 
        *to++= *from++;
456
 
      from--;
457
 
      continue;
458
 
    }
459
 
    /*
460
 
     If the next character appears to begin a multi-byte character, we
461
 
     escape that first byte of that apparent multi-byte character. (The
462
 
     character just looks like a multi-byte character -- if it were actually
463
 
     a multi-byte character, it would have been passed through in the test
464
 
     above.)
465
 
 
466
 
     Without this check, we can create a problem by converting an invalid
467
 
     multi-byte character into a valid one. For example, 0xbf27 is not
468
 
     a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \)
469
 
    */
470
 
    if (use_mb_flag && (tmp_length= my_mbcharlen(charset_info, *from)) > 1)
471
 
      escape= *from;
472
 
    else
473
 
#endif
474
 
    switch (*from) {
475
 
    case 0:                             /* Must be escaped for 'mysql' */
476
 
      escape= '0';
477
 
      break;
478
 
    case '\n':                          /* Must be escaped for logs */
479
 
      escape= 'n';
480
 
      break;
481
 
    case '\r':
482
 
      escape= 'r';
483
 
      break;
484
 
    case '\\':
485
 
      escape= '\\';
486
 
      break;
487
 
    case '\'':
488
 
      escape= '\'';
489
 
      break;
490
 
    case '"':                           /* Better safe than sorry */
491
 
      escape= '"';
492
 
      break;
493
 
    case '\032':                        /* This gives problems on Win32 */
494
 
      escape= 'Z';
495
 
      break;
496
 
    }
497
 
    if (escape)
498
 
    {
499
 
      if (to + 2 > to_end)
500
 
      {
501
 
        overflow= true;
502
 
        break;
503
 
      }
504
 
      *to++= '\\';
505
 
      *to++= escape;
506
 
    }
507
 
    else
508
 
    {
509
 
      if (to + 1 > to_end)
510
 
      {
511
 
        overflow= true;
512
 
        break;
513
 
      }
514
 
      *to++= *from;
515
 
    }
516
 
  }
517
 
  *to= 0;
518
 
  return overflow ? (size_t) -1 : (size_t) (to - to_start);
519
 
}
520
 
 
521
 
 
522
407
#ifdef BACKSLASH_MBTAIL
523
408
static CHARSET_INFO *fs_cset_cache= NULL;
524
409