~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/backend/utils/adt/formatting.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt, CVE-2013-1899
  • Date: 2013-04-02 12:24:32 UTC
  • mfrom: (1.1.11)
  • Revision ID: package-import@ubuntu.com-20130402122432-whgoxuhc5tqte9v4
Tags: 9.1.9-0ubuntu11.10
* New upstream security/bug fix release: (LP: #1163184)
  - Fix insecure parsing of server command-line switches.
    A connection request containing a database name that begins with
    "-" could be crafted to damage or destroy files within the server's
    data directory, even if the request is eventually rejected.
    [CVE-2013-1899]
  - Reset OpenSSL randomness state in each postmaster child process.
    This avoids a scenario wherein random numbers generated by
    "contrib/pgcrypto" functions might be relatively easy for another
    database user to guess. The risk is only significant when the
    postmaster is configured with ssl = on but most connections don't
    use SSL encryption. [CVE-2013-1900]
  - Make REPLICATION privilege checks test current user not
    authenticated user.
    An unprivileged database user could exploit this mistake to call
    pg_start_backup() or pg_stop_backup(), thus possibly interfering
    with creation of routine backups. [CVE-2013-1901]
  - Fix GiST indexes to not use "fuzzy" geometric comparisons when it's
    not appropriate to do so.
    The core geometric types perform comparisons using "fuzzy"
    equality, but gist_box_same must do exact comparisons, else GiST
    indexes using it might become inconsistent. After installing this
    update, users should "REINDEX" any GiST indexes on box, polygon,
    circle, or point columns, since all of these use gist_box_same.
  - Fix erroneous range-union and penalty logic in GiST indexes that
    use "contrib/btree_gist" for variable-width data types, that is
    text, bytea, bit, and numeric columns.
    These errors could result in inconsistent indexes in which some
    keys that are present would not be found by searches, and also in
    useless index bloat. Users are advised to "REINDEX" such indexes
    after installing this update.
  - Fix bugs in GiST page splitting code for multi-column indexes.
    These errors could result in inconsistent indexes in which some
    keys that are present would not be found by searches, and also in
    indexes that are unnecessarily inefficient to search. Users are
    advised to "REINDEX" multi-column GiST indexes after installing
    this update.
  - See HISTORY/changelog.gz for details about the other bug fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1491
1491
        /* C/POSIX collations use this path regardless of database encoding */
1492
1492
        if (lc_ctype_is_c(collid))
1493
1493
        {
1494
 
                char       *p;
1495
 
 
1496
 
                result = pnstrdup(buff, nbytes);
1497
 
 
1498
 
                for (p = result; *p; p++)
1499
 
                        *p = pg_ascii_tolower((unsigned char) *p);
 
1494
                result = asc_tolower(buff, nbytes);
1500
1495
        }
1501
1496
#ifdef USE_WIDE_UPPER_LOWER
1502
1497
        else if (pg_database_encoding_max_length() > 1)
1612
1607
        /* C/POSIX collations use this path regardless of database encoding */
1613
1608
        if (lc_ctype_is_c(collid))
1614
1609
        {
1615
 
                char       *p;
1616
 
 
1617
 
                result = pnstrdup(buff, nbytes);
1618
 
 
1619
 
                for (p = result; *p; p++)
1620
 
                        *p = pg_ascii_toupper((unsigned char) *p);
 
1610
                result = asc_toupper(buff, nbytes);
1621
1611
        }
1622
1612
#ifdef USE_WIDE_UPPER_LOWER
1623
1613
        else if (pg_database_encoding_max_length() > 1)
1734
1724
        /* C/POSIX collations use this path regardless of database encoding */
1735
1725
        if (lc_ctype_is_c(collid))
1736
1726
        {
1737
 
                char       *p;
1738
 
 
1739
 
                result = pnstrdup(buff, nbytes);
1740
 
 
1741
 
                for (p = result; *p; p++)
1742
 
                {
1743
 
                        char            c;
1744
 
 
1745
 
                        if (wasalnum)
1746
 
                                *p = c = pg_ascii_tolower((unsigned char) *p);
1747
 
                        else
1748
 
                                *p = c = pg_ascii_toupper((unsigned char) *p);
1749
 
                        /* we don't trust isalnum() here */
1750
 
                        wasalnum = ((c >= 'A' && c <= 'Z') ||
1751
 
                                                (c >= 'a' && c <= 'z') ||
1752
 
                                                (c >= '0' && c <= '9'));
1753
 
                }
 
1727
                result = asc_initcap(buff, nbytes);
1754
1728
        }
1755
1729
#ifdef USE_WIDE_UPPER_LOWER
1756
1730
        else if (pg_database_encoding_max_length() > 1)
1873
1847
        return result;
1874
1848
}
1875
1849
 
 
1850
/*
 
1851
 * ASCII-only lower function
 
1852
 *
 
1853
 * We pass the number of bytes so we can pass varlena and char*
 
1854
 * to this function.  The result is a palloc'd, null-terminated string.
 
1855
 */
 
1856
char *
 
1857
asc_tolower(const char *buff, size_t nbytes)
 
1858
{
 
1859
        char       *result;
 
1860
        char       *p;
 
1861
 
 
1862
        if (!buff)
 
1863
                return NULL;
 
1864
 
 
1865
        result = pnstrdup(buff, nbytes);
 
1866
 
 
1867
        for (p = result; *p; p++)
 
1868
                *p = pg_ascii_tolower((unsigned char) *p);
 
1869
 
 
1870
        return result;
 
1871
}
 
1872
 
 
1873
/*
 
1874
 * ASCII-only upper function
 
1875
 *
 
1876
 * We pass the number of bytes so we can pass varlena and char*
 
1877
 * to this function.  The result is a palloc'd, null-terminated string.
 
1878
 */
 
1879
char *
 
1880
asc_toupper(const char *buff, size_t nbytes)
 
1881
{
 
1882
        char       *result;
 
1883
        char       *p;
 
1884
 
 
1885
        if (!buff)
 
1886
                return NULL;
 
1887
 
 
1888
        result = pnstrdup(buff, nbytes);
 
1889
 
 
1890
        for (p = result; *p; p++)
 
1891
                *p = pg_ascii_toupper((unsigned char) *p);
 
1892
 
 
1893
        return result;
 
1894
}
 
1895
 
 
1896
/*
 
1897
 * ASCII-only initcap function
 
1898
 *
 
1899
 * We pass the number of bytes so we can pass varlena and char*
 
1900
 * to this function.  The result is a palloc'd, null-terminated string.
 
1901
 */
 
1902
char *
 
1903
asc_initcap(const char *buff, size_t nbytes)
 
1904
{
 
1905
        char       *result;
 
1906
        char       *p;
 
1907
        int                     wasalnum = false;
 
1908
 
 
1909
        if (!buff)
 
1910
                return NULL;
 
1911
 
 
1912
        result = pnstrdup(buff, nbytes);
 
1913
 
 
1914
        for (p = result; *p; p++)
 
1915
        {
 
1916
                char            c;
 
1917
 
 
1918
                if (wasalnum)
 
1919
                        *p = c = pg_ascii_tolower((unsigned char) *p);
 
1920
                else
 
1921
                        *p = c = pg_ascii_toupper((unsigned char) *p);
 
1922
                /* we don't trust isalnum() here */
 
1923
                wasalnum = ((c >= 'A' && c <= 'Z') ||
 
1924
                                        (c >= 'a' && c <= 'z') ||
 
1925
                                        (c >= '0' && c <= '9'));
 
1926
        }
 
1927
 
 
1928
        return result;
 
1929
}
 
1930
 
1876
1931
/* convenience routines for when the input is null-terminated */
1877
1932
 
1878
1933
static char *
1893
1948
        return str_initcap(buff, strlen(buff), collid);
1894
1949
}
1895
1950
 
 
1951
static char *
 
1952
asc_tolower_z(const char *buff)
 
1953
{
 
1954
        return asc_tolower(buff, strlen(buff));
 
1955
}
 
1956
 
 
1957
static char *
 
1958
asc_toupper_z(const char *buff)
 
1959
{
 
1960
        return asc_toupper(buff, strlen(buff));
 
1961
}
 
1962
 
 
1963
/* asc_initcap_z is not currently needed */
 
1964
 
1896
1965
 
1897
1966
/* ----------
1898
1967
 * Skip TM / th in FROM_CHAR
2380
2449
                                INVALID_FOR_INTERVAL;
2381
2450
                                if (tmtcTzn(in))
2382
2451
                                {
2383
 
                                        char       *p = str_tolower_z(tmtcTzn(in), collid);
 
2452
                                        /* We assume here that timezone names aren't localized */
 
2453
                                        char       *p = asc_tolower_z(tmtcTzn(in));
2384
2454
 
2385
2455
                                        strcpy(s, p);
2386
2456
                                        pfree(p);
2427
2497
                                        strcpy(s, str_toupper_z(localized_full_months[tm->tm_mon - 1], collid));
2428
2498
                                else
2429
2499
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2430
 
                                                 str_toupper_z(months_full[tm->tm_mon - 1], collid));
 
2500
                                                 asc_toupper_z(months_full[tm->tm_mon - 1]));
2431
2501
                                s += strlen(s);
2432
2502
                                break;
2433
2503
                        case DCH_Month:
2437
2507
                                if (S_TM(n->suffix))
2438
2508
                                        strcpy(s, str_initcap_z(localized_full_months[tm->tm_mon - 1], collid));
2439
2509
                                else
2440
 
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, months_full[tm->tm_mon - 1]);
 
2510
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
 
2511
                                                        months_full[tm->tm_mon - 1]);
2441
2512
                                s += strlen(s);
2442
2513
                                break;
2443
2514
                        case DCH_month:
2447
2518
                                if (S_TM(n->suffix))
2448
2519
                                        strcpy(s, str_tolower_z(localized_full_months[tm->tm_mon - 1], collid));
2449
2520
                                else
2450
 
                                {
2451
 
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, months_full[tm->tm_mon - 1]);
2452
 
                                        *s = pg_tolower((unsigned char) *s);
2453
 
                                }
 
2521
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
 
2522
                                                        asc_tolower_z(months_full[tm->tm_mon - 1]));
2454
2523
                                s += strlen(s);
2455
2524
                                break;
2456
2525
                        case DCH_MON:
2460
2529
                                if (S_TM(n->suffix))
2461
2530
                                        strcpy(s, str_toupper_z(localized_abbrev_months[tm->tm_mon - 1], collid));
2462
2531
                                else
2463
 
                                        strcpy(s, str_toupper_z(months[tm->tm_mon - 1], collid));
 
2532
                                        strcpy(s, asc_toupper_z(months[tm->tm_mon - 1]));
2464
2533
                                s += strlen(s);
2465
2534
                                break;
2466
2535
                        case DCH_Mon:
2480
2549
                                if (S_TM(n->suffix))
2481
2550
                                        strcpy(s, str_tolower_z(localized_abbrev_months[tm->tm_mon - 1], collid));
2482
2551
                                else
2483
 
                                {
2484
 
                                        strcpy(s, months[tm->tm_mon - 1]);
2485
 
                                        *s = pg_tolower((unsigned char) *s);
2486
 
                                }
 
2552
                                        strcpy(s, asc_tolower_z(months[tm->tm_mon - 1]));
2487
2553
                                s += strlen(s);
2488
2554
                                break;
2489
2555
                        case DCH_MM:
2498
2564
                                        strcpy(s, str_toupper_z(localized_full_days[tm->tm_wday], collid));
2499
2565
                                else
2500
2566
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
2501
 
                                                        str_toupper_z(days[tm->tm_wday], collid));
 
2567
                                                        asc_toupper_z(days[tm->tm_wday]));
2502
2568
                                s += strlen(s);
2503
2569
                                break;
2504
2570
                        case DCH_Day:
2506
2572
                                if (S_TM(n->suffix))
2507
2573
                                        strcpy(s, str_initcap_z(localized_full_days[tm->tm_wday], collid));
2508
2574
                                else
2509
 
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, days[tm->tm_wday]);
 
2575
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
 
2576
                                                        days[tm->tm_wday]);
2510
2577
                                s += strlen(s);
2511
2578
                                break;
2512
2579
                        case DCH_day:
2514
2581
                                if (S_TM(n->suffix))
2515
2582
                                        strcpy(s, str_tolower_z(localized_full_days[tm->tm_wday], collid));
2516
2583
                                else
2517
 
                                {
2518
 
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9, days[tm->tm_wday]);
2519
 
                                        *s = pg_tolower((unsigned char) *s);
2520
 
                                }
 
2584
                                        sprintf(s, "%*s", S_FM(n->suffix) ? 0 : -9,
 
2585
                                                        asc_tolower_z(days[tm->tm_wday]));
2521
2586
                                s += strlen(s);
2522
2587
                                break;
2523
2588
                        case DCH_DY:
2525
2590
                                if (S_TM(n->suffix))
2526
2591
                                        strcpy(s, str_toupper_z(localized_abbrev_days[tm->tm_wday], collid));
2527
2592
                                else
2528
 
                                        strcpy(s, str_toupper_z(days_short[tm->tm_wday], collid));
 
2593
                                        strcpy(s, asc_toupper_z(days_short[tm->tm_wday]));
2529
2594
                                s += strlen(s);
2530
2595
                                break;
2531
2596
                        case DCH_Dy:
2541
2606
                                if (S_TM(n->suffix))
2542
2607
                                        strcpy(s, str_tolower_z(localized_abbrev_days[tm->tm_wday], collid));
2543
2608
                                else
2544
 
                                {
2545
 
                                        strcpy(s, days_short[tm->tm_wday]);
2546
 
                                        *s = pg_tolower((unsigned char) *s);
2547
 
                                }
 
2609
                                        strcpy(s, asc_tolower_z(days_short[tm->tm_wday]));
2548
2610
                                s += strlen(s);
2549
2611
                                break;
2550
2612
                        case DCH_DDD:
4651
4713
                                case NUM_rn:
4652
4714
                                        if (IS_FILLMODE(Np->Num))
4653
4715
                                        {
4654
 
                                                strcpy(Np->inout_p, str_tolower_z(Np->number_p, collid));
 
4716
                                                strcpy(Np->inout_p, asc_tolower_z(Np->number_p));
4655
4717
                                                Np->inout_p += strlen(Np->inout_p) - 1;
4656
4718
                                        }
4657
4719
                                        else
4658
4720
                                        {
4659
 
                                                sprintf(Np->inout_p, "%15s", str_tolower_z(Np->number_p, collid));
 
4721
                                                sprintf(Np->inout_p, "%15s", asc_tolower_z(Np->number_p));
4660
4722
                                                Np->inout_p += strlen(Np->inout_p) - 1;
4661
4723
                                        }
4662
4724
                                        break;