Пример #1
0
/* 
 *  Test every possible word value. 
 *  Once we are finished, retest every possible word value.
 *  if the test fails on the following null word, iterate test_nrange 
 *  again, appending another word.
 *  This assures the output order of the two tests are in sync.
 */
void test_wrange(struct testval *p)
{
    struct testval f, l, s;
    apr_status_t rc;
    int success = 0;
    
    memcpy (&s, p, sizeof(s));
    ++s.wl;    
    
    do {
        apr_size_t nl = sizeof(s.n), wl = s.wl;        
        rc = apr_conv_ucs2_to_utf8(s.w, &wl, s.n, &nl);
        s.nl = sizeof(s.n) - nl;
        if (!wl && rc == APR_SUCCESS) {
            if (!success) {
                memcpy(&f, &s, sizeof(s));
                success = -1;
            }
            else {
                if (s.nl != l.nl 
                 || memcmp(s.n, l.n, s.nl - 1) != 0
                 || s.n[s.nl - 1] != l.n[l.nl - 1] + 1) {
                    displaynw(&f, &l);
                    memcpy(&f, &s, sizeof(s));
                }
            }            
            memcpy(&l, &s, sizeof(s));
        }
        else {
            if (success) {
                displaynw(&f, &l);
                success = 0;
            }
        }
    } while (++s.w[s.wl - 1]);

    if (success) {
        displaynw(&f, &l);
        success = 0;
    }

    do {
        int wl = s.wl, nl = sizeof(s.n);
        rc = apr_conv_ucs2_to_utf8(s.w, &wl, s.n, &nl);
        s.nl = sizeof(s.n) - s.nl;
        if (rc == APR_INCOMPLETE) {
            test_wrange(&s);
        }
    } while (++s.w[s.wl - 1]);
}
Пример #2
0
/* Used by apr_app_initialize to reprocess the environment
 *
 * An internal apr function to convert a double-null terminated set
 * of single-null terminated strings from wide Unicode to narrow utf-8
 * as a list of strings.  These are allocated from the MSVCRT's
 * _CRT_BLOCK to trick the system into trusting our store.
 */
static int warrsztoastr(const char * const * *retarr,
                        const wchar_t * arrsz, int args)
{
    const apr_wchar_t *wch;
    apr_size_t totlen;
    apr_size_t newlen;
    apr_size_t wsize;
    char **env;
    char *pstrs;
    char *strs;
    int arg;

    if (args < 0) {
        for (args = 1, wch = arrsz; wch[0] || wch[1]; ++wch)
            if (!*wch)
                ++args;
    }
    wsize = 1 + wch - arrsz;

    /* This is a safe max allocation, we will alloc each
     * string exactly after processing and return this
     * temporary buffer to the free store.
     * 3 ucs bytes hold any single wchar_t value (16 bits)
     * 4 ucs bytes will hold a wchar_t pair value (20 bits)
     */
    newlen = totlen = wsize * 3 + 1;
    pstrs = strs = apr_malloc_dbg(newlen * sizeof(char),
                                  __FILE__, __LINE__);

    (void)apr_conv_ucs2_to_utf8(arrsz, &wsize, strs, &newlen);

    assert(newlen && !wsize);

    *retarr = env = apr_malloc_dbg((args + 1) * sizeof(char*),
                                   __FILE__, __LINE__);
    for (arg = 0; arg < args; ++arg) {
        char* p = pstrs;
        int len = 0;
        while (*p++)
            ++len;
        len += 1;

        *env = apr_malloc_dbg(len * sizeof(char),
                              __FILE__, __LINE__);
        memcpy(*env, pstrs, len * sizeof(char));

        pstrs += len;
        ++env;
    }

    *env = NULL;
    free(strs);

    return args;
}
Пример #3
0
static
apr_status_t
TextConsoleRead(
    void *opaque,
    apr_byte_t *buffer,
    apr_size_t bytesToRead,
    apr_size_t *bytesRead
    )
{
    apr_status_t status;
    apr_size_t bytesRemaining = bytesToRead;
    apr_size_t charsRemaining;
    apr_wchar_t inBuffer[1];
    char *offset;
    HANDLE console = opaque;

    ASSERT(opaque != NULL);
    ASSERT(buffer != NULL);
    ASSERT(console != INVALID_HANDLE_VALUE);
    ASSERT(EncGetCurrent() == ENCODING_UTF8);

    do {
        // Read one character at a time so we don't over-request
        if (!ReadConsoleFullW(console, inBuffer, 1, (DWORD *)&charsRemaining)) {
            status = apr_get_os_error();
        } else {
            // Convert the UCS-2 character to UTF-8
            offset = (char *)buffer + (bytesToRead - bytesRemaining);
            status = apr_conv_ucs2_to_utf8(inBuffer, &charsRemaining, offset, &bytesRemaining);
        }
    } while (status == APR_SUCCESS && bytesRemaining > 0);

    if (bytesRead != NULL) {
        *bytesRead = bytesToRead - bytesRemaining;
    }
    return status;
}
Пример #4
0
AP_DECLARE(apr_status_t) ap_os_proc_filepath(char **binpath, apr_pool_t *p)
{
    apr_wchar_t wbinpath[APR_PATH_MAX];

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE 
    {
        apr_size_t binlen;
        apr_size_t wbinlen;
        apr_status_t rv;
        if (!GetModuleFileNameW(NULL, wbinpath, sizeof(wbinpath) 
                                              / sizeof(apr_wchar_t))) {
            return apr_get_os_error();
        }
        wbinlen = wcslen(wbinpath) + 1;
        binlen = (wbinlen - 1) * 3 + 1;
        *binpath = apr_palloc(p, binlen);
        rv = apr_conv_ucs2_to_utf8(wbinpath, &wbinlen, *binpath, &binlen);
        if (rv != APR_SUCCESS)
            return rv;
        else if (wbinlen)
            return APR_ENAMETOOLONG;
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        /* share the same scratch buffer */
        char *pathbuf = (char*) wbinpath;
        if (!GetModuleFileName(NULL, pathbuf, sizeof(wbinpath))) {
            return apr_get_os_error();
        }
        *binpath = apr_pstrdup(p, pathbuf);
    }
#endif
    return APR_SUCCESS;
}
Пример #5
0
AP_DECLARE(apr_status_t) ap_regkey_value_array_get(apr_array_header_t **result,
                                                   ap_regkey_t *key,
                                                   const char *valuename,
                                                   apr_pool_t *pool)
{
    /* Retrieve a registry string value, and explode any envvars
     * that the system has configured (e.g. %SystemRoot%/someapp.exe)
     */
    apr_status_t rv;
    void *value;
    char *buf;
    char *tmp;
    apr_int32_t type;
    apr_size_t size = 0;

    rv = ap_regkey_value_raw_get(&value, &size, &type, key, valuename, pool);
    if (rv != APR_SUCCESS) {
        return rv;
    }
    else if (type != REG_MULTI_SZ) {
        return APR_EINVAL;
    }

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
        apr_size_t alloclen;
        apr_size_t valuelen = strlen(valuename) + 1;

        /* ###: deliberately overallocate plus two extra nulls.
         * We could precalculate the exact buffer here instead, the question
         * is a matter of storage v.s. cpu cycles.
         */
        size /= 2;
        alloclen = valuelen = size * 3 + 2;
        buf = apr_palloc(pool, valuelen);
        rv = apr_conv_ucs2_to_utf8(value, &size, buf, &valuelen);
        if (rv != APR_SUCCESS)
            return rv;
        else if (size)
            return APR_ENAMETOOLONG;
        buf[(alloclen - valuelen)] = '\0';
        buf[(alloclen - valuelen) + 1] = '\0';
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        /* Small possiblity the array is either unterminated
         * or single NULL terminated.  Avert.
         */
        buf = (char *)value;
        if (size < 2 || buf[size - 1] != '\0' || buf[size - 2] != '\0') {
            buf = apr_palloc(pool, size + 2);
            memcpy(buf, value, size);
            buf[size + 1] = '\0';
            buf[size] = '\0';
        }
    }
#endif

    size = 0;    /* Element Count */
    for (tmp = buf; *tmp; ++tmp) {
        ++size;
        while (*tmp) {
            ++tmp;
        }
    }

    *result = apr_array_make(pool, (int)size, sizeof(char *));
    for (tmp = buf; *tmp; ++tmp) {
        char **newelem = (char **) apr_array_push(*result);
        *newelem = tmp;
        while (*tmp) {
            ++tmp;
        }
    }

   return APR_SUCCESS;
}
Пример #6
0
AP_DECLARE(apr_status_t) ap_regkey_value_get(char **result,
                                             ap_regkey_t *key,
                                             const char *valuename,
                                             apr_pool_t *pool)
{
    /* Retrieve a registry string value, and explode any envvars
     * that the system has configured (e.g. %SystemRoot%/someapp.exe)
     */
    LONG rc;
    DWORD type;
    apr_size_t size = 0;

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
        apr_size_t valuelen = strlen(valuename) + 1;
        apr_size_t wvallen = 256;
        apr_wchar_t wvalname[256];
        apr_wchar_t *wvalue;
        apr_status_t rv;
        rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen);
        if (rv != APR_SUCCESS)
            return rv;
        else if (valuelen)
            return APR_ENAMETOOLONG;
        /* Read to NULL buffer to determine value size */
        rc = RegQueryValueExW(key->hkey, wvalname, 0, &type, NULL, (DWORD *)&size);
        if (rc != ERROR_SUCCESS) {
            return APR_FROM_OS_ERROR(rc);
        }
        if ((size < 2) || (type != REG_SZ && type != REG_EXPAND_SZ)) {
            return APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER);
        }

        wvalue = apr_palloc(pool, size);
        /* Read value based on size query above */
        rc = RegQueryValueExW(key->hkey, wvalname, 0, &type,
                              (LPBYTE)wvalue, (DWORD *)&size);
        if (rc != ERROR_SUCCESS) {
            return APR_FROM_OS_ERROR(rc);
        }
        if (type == REG_EXPAND_SZ) {
            apr_wchar_t zbuf[1];
            size = ExpandEnvironmentStringsW(wvalue, zbuf, 0);
            if (size) {
                apr_wchar_t *tmp = wvalue;
                /* The size returned by ExpandEnvironmentStringsW is wchars */
                wvalue = apr_palloc(pool, size * 2);
                size = ExpandEnvironmentStringsW(tmp, wvalue, (DWORD)size);
            }
        }
        else {
            /* count wchars from RegQueryValueExW, rather than bytes */
            size /= 2;
        }
        /* ###: deliberately overallocate all but the trailing null.
         * We could precalculate the exact buffer here instead, the question
         * is a matter of storage v.s. cpu cycles.
         */
        valuelen = (size - 1) * 3 + 1;
        *result = apr_palloc(pool, valuelen);
        rv = apr_conv_ucs2_to_utf8(wvalue, &size, *result, &valuelen);
        if (rv != APR_SUCCESS)
            return rv;
        else if (size)
            return APR_ENAMETOOLONG;
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        /* Read to NULL buffer to determine value size */
        rc = RegQueryValueEx(key->hkey, valuename, 0, &type, NULL, (DWORD *)&size);
        if (rc != ERROR_SUCCESS)
            return APR_FROM_OS_ERROR(rc);

        if ((size < 1) || (type != REG_SZ && type != REG_EXPAND_SZ)) {
            return APR_FROM_OS_ERROR(ERROR_INVALID_PARAMETER);
        }

        *result = apr_palloc(pool, size);
        /* Read value based on size query above */
        rc = RegQueryValueEx(key->hkey, valuename, 0, &type, *result, (DWORD *)&size);
        if (rc != ERROR_SUCCESS)
            return APR_FROM_OS_ERROR(rc);

        if (type == REG_EXPAND_SZ) {
            /* Advise ExpandEnvironmentStrings that we have a zero char
             * buffer to force computation of the required length.
             */
            char zbuf[1];
            size = ExpandEnvironmentStrings(*result, zbuf, 0);
            if (size) {
                char *tmp = *result;
                *result = apr_palloc(pool, size);
                size = ExpandEnvironmentStrings(tmp, *result, (DWORD)size);
            }
        }
    }
#endif
    return APR_SUCCESS;
}
Пример #7
0
/* Shared by apr_app.c and start.c 
 *
 * An internal apr function to convert an array of strings (either
 * a counted or NULL terminated list, such as an argv[argc] or env[]
 * list respectively) from wide Unicode strings to narrow utf-8 strings.
 * These are allocated from the MSVCRT's _CRT_BLOCK to trick the system
 * into trusting our store.
 */
int apr_wastrtoastr(char const * const * *retarr, 
                    wchar_t const * const *arr, int args)
{
    apr_size_t elesize = 0;
    char **newarr;
    char *elements;
    char *ele;
    int arg;

    if (args < 0) {
        for (args = 0; arr[args]; ++args)
            ;
    }

    newarr = _malloc_dbg((args + 1) * sizeof(char *),
                         _CRT_BLOCK, __FILE__, __LINE__);

    for (arg = 0; arg < args; ++arg) {
        newarr[arg] = (void*)(wcslen(arr[arg]) + 1);
        elesize += (apr_size_t)newarr[arg];
    }

    /* This is a safe max allocation, we will realloc after
     * processing and return the excess to the free store.
     * 3 ucs bytes hold any single wchar_t value (16 bits)
     * 4 ucs bytes will hold a wchar_t pair value (20 bits)
     */
    elesize = elesize * 3 + 1;
    ele = elements = _malloc_dbg(elesize * sizeof(char), 
                                 _CRT_BLOCK, __FILE__, __LINE__);

    for (arg = 0; arg < args; ++arg) {
        apr_size_t len = (apr_size_t)newarr[arg];
        apr_size_t newlen = elesize;

        newarr[arg] = ele;
        (void)apr_conv_ucs2_to_utf8(arr[arg], &len,
                                    newarr[arg], &elesize);

        newlen -= elesize;
        ele += newlen;
        assert(elesize && (len == 0));
    }

    newarr[arg] = NULL;
    *(ele++) = '\0';

    /* Return to the free store if the heap realloc is the least bit optimized
     */
    ele = _realloc_dbg(elements, ele - elements, 
                       _CRT_BLOCK, __FILE__, __LINE__);

    if (ele != elements) {
        apr_size_t diff = ele - elements;
        for (arg = 0; arg < args; ++arg) {
            newarr[arg] += diff;
        }
    }

    *retarr = newarr;
    return args;
}
Пример #8
0
svn_error_t *
svn_nls_init(void)
{
    svn_error_t *err = SVN_NO_ERROR;

#ifdef ENABLE_NLS
#ifdef WIN32
    {
        WCHAR ucs2_path[MAX_PATH];
        char* utf8_path;
        const char* internal_path;
        apr_pool_t* pool;
        apr_status_t apr_err;
        apr_size_t inwords, outbytes, outlength;

        apr_pool_create(&pool, 0);
        /* get exe name - our locale info will be in '../share/locale' */
        inwords = GetModuleFileNameW(0, ucs2_path,
                                     sizeof(ucs2_path) / sizeof(ucs2_path[0]));
        if (! inwords)
        {
            /* We must be on a Win9x machine, so attempt to get an ANSI path,
               and convert it to Unicode. */
            CHAR ansi_path[MAX_PATH];

            if (GetModuleFileNameA(0, ansi_path, sizeof(ansi_path)))
            {
                inwords =
                    MultiByteToWideChar(CP_ACP, 0, ansi_path, -1, ucs2_path,
                                        sizeof(ucs2_path) / sizeof(ucs2_path[0]));
                if (! inwords) {
                    err =
                        svn_error_createf(APR_EINVAL, NULL,
                                          _("Can't convert string to UCS-2: '%s'"),
                                          ansi_path);
                }
            }
            else
            {
                err = svn_error_create(APR_EINVAL, NULL,
                                       _("Can't get module file name"));
            }
        }

        if (! err)
        {
            outbytes = outlength = 3 * (inwords + 1);
            utf8_path = apr_palloc(pool, outlength);
            apr_err = apr_conv_ucs2_to_utf8(ucs2_path, &inwords,
                                            utf8_path, &outbytes);
            if (!apr_err && (inwords > 0 || outbytes == 0))
                apr_err = APR_INCOMPLETE;
            if (apr_err)
            {
                err = svn_error_createf(apr_err, NULL,
                                        _("Can't convert module path "
                                          "to UTF-8 from UCS-2: '%s'"),
                                        ucs2_path);
            }
            else
            {
                utf8_path[outlength - outbytes] = '\0';
                internal_path = svn_path_internal_style(utf8_path, pool);
                /* get base path name */
                internal_path = svn_path_dirname(internal_path, pool);
                internal_path = svn_path_join(internal_path,
                                              SVN_LOCALE_RELATIVE_PATH,
                                              pool);
                bindtextdomain(PACKAGE_NAME, internal_path);
            }
        }
        svn_pool_destroy(pool);
    }
#else
    bindtextdomain(PACKAGE_NAME, SVN_LOCALE_DIR);
#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
    bind_textdomain_codeset(PACKAGE_NAME, "UTF-8");
#endif
#endif
#endif

    return err;
}
Пример #9
0
/**
 * Initialize the environment for all requests.
 * @param env   the JNI environment for this request
 */
bool JNIUtil::JNIGlobalInit(JNIEnv *env)
{
  // This method has to be run only once during the run a program.
  static bool run = false;
  svn_error_t *err;
  if (run) // already run
    return true;

  run = true;

  // Do not run this part more than one time.  This leaves a small
  // time window when two threads create their first SVNClient and
  // SVNAdmin at the same time, but I do not see a better option
  // without APR already initialized
  if (g_inInit)
    return false;

  g_inInit = true;
  g_initEnv = env;

  apr_status_t status;



  /* Initialize the APR subsystem, and register an atexit() function
   * to Uninitialize that subsystem at program exit. */
  status = apr_initialize();
  if (status)
    {
      if (stderr)
        {
          char buf[1024];
          apr_strerror(status, buf, sizeof(buf) - 1);
          fprintf(stderr,
                  "%s: error: cannot initialize APR: %s\n",
                  "svnjavahl", buf);
        }
      return FALSE;
    }

  /* This has to happen before any pools are created. */
  if ((err = svn_dso_initialize2()))
    {
      if (stderr && err->message)
        fprintf(stderr, "%s", err->message);

      svn_error_clear(err);
      return FALSE;
    }

  if (0 > atexit(apr_terminate))
    {
      if (stderr)
        fprintf(stderr,
                "%s: error: atexit registration failed\n",
                "svnjavahl");
      return FALSE;
    }

  /* Create our top-level pool. */
  g_pool = svn_pool_create(NULL);

  apr_allocator_t* allocator = apr_pool_allocator_get(g_pool);

  if (allocator)
    {
      /* Keep a maximum of 1 free block, to release memory back to the JVM
         (and other modules). */
      apr_allocator_max_free_set(allocator, 1);
    }

  svn_utf_initialize2(FALSE, g_pool); /* Optimize character conversions */
  svn_fs_initialize(g_pool); /* Avoid some theoretical issues */
  svn_ra_initialize(g_pool);

  /* We shouldn't fill the JVMs memory with FS cache data unless explictly
     requested. */
  {
    svn_cache_config_t settings = *svn_cache_config_get();
    settings.cache_size = 0;
    settings.file_handle_count = 0;
    settings.single_threaded = FALSE;
    svn_cache_config_set(&settings);
  }

#ifdef ENABLE_NLS
#ifdef WIN32
  {
    WCHAR ucs2_path[MAX_PATH];
    char *utf8_path;
    const char *internal_path;
    apr_pool_t *pool;
    apr_status_t apr_err;
    apr_size_t inwords, outbytes;
    unsigned int outlength;

    pool = svn_pool_create(g_pool);
    /* get dll name - our locale info will be in '../share/locale' */
    inwords = sizeof(ucs2_path) / sizeof(ucs2_path[0]);
    HINSTANCE moduleHandle = GetModuleHandle("libsvnjavahl-1");
    GetModuleFileNameW(moduleHandle, ucs2_path, inwords);
    inwords = lstrlenW(ucs2_path);
    outbytes = outlength = 3 * (inwords + 1);
    utf8_path = reinterpret_cast<char *>(apr_palloc(pool, outlength));
    apr_err = apr_conv_ucs2_to_utf8((const apr_wchar_t *) ucs2_path,
                                    &inwords, utf8_path, &outbytes);
    if (!apr_err && (inwords > 0 || outbytes == 0))
      apr_err = APR_INCOMPLETE;
    if (apr_err)
      {
        if (stderr)
          fprintf(stderr, "Can't convert module path to UTF-8");
        return FALSE;
      }
    utf8_path[outlength - outbytes] = '\0';
    internal_path = svn_dirent_internal_style(utf8_path, pool);
    /* get base path name */
    internal_path = svn_dirent_dirname(internal_path, pool);
    internal_path = svn_dirent_join(internal_path, SVN_LOCALE_RELATIVE_PATH,
                                  pool);
    bindtextdomain(PACKAGE_NAME, internal_path);
    svn_pool_destroy(pool);
  }
#else
  bindtextdomain(PACKAGE_NAME, SVN_LOCALE_DIR);
#endif
#endif

#if defined(WIN32) || defined(__CYGWIN__)
  /* See http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt */
  /* ### This code really only needs to be invoked by consumers of
     ### the libsvn_wc library, which basically means SVNClient. */
  if (getenv("SVN_ASP_DOT_NET_HACK"))
    {
      err = svn_wc_set_adm_dir("_svn", g_pool);
      if (err)
        {
          if (stderr)
            {
              fprintf(stderr,
                      "%s: error: SVN_ASP_DOT_NET_HACK failed: %s\n",
                      "svnjavahl", err->message);
            }
          svn_error_clear(err);
          return FALSE;
        }
    }
#endif

  svn_error_set_malfunction_handler(svn_error_raise_on_malfunction);

  // Build all mutexes.
  g_finalizedObjectsMutex = new JNIMutex(g_pool);
  if (isExceptionThrown())
    return false;

  g_logMutex = new JNIMutex(g_pool);
  if (isExceptionThrown())
    return false;

  // initialized the thread local storage
  if (!JNIThreadData::initThreadData())
    return false;

  setEnv(env);
  if (isExceptionThrown())
    return false;

  g_initEnv = NULL;
  g_inInit = false;
  return true;
}
Пример #10
0
/*
 *  Test every possible byte value. 
 *  If the test passes or fails at this byte value we are done.
 *  Otherwise iterate test_nrange again, appending another byte.
 */
void test_ranges()
{
    struct testval ntest, wtest;
    apr_status_t nrc, wrc;
    apr_size_t inlen;
    unsigned long matches = 0;

    memset(&ntest, 0, sizeof(ntest));
    ++ntest.nl;

    memset(&wtest, 0, sizeof(wtest));
    ++wtest.wl;

    do {
        do {
            inlen = ntest.nl;
            ntest.wl = sizeof(ntest.w) / 2;
            nrc = apr_conv_utf8_to_ucs2(ntest.n, &inlen, ntest.w, &ntest.wl);
            if (nrc == APR_SUCCESS) {
                ntest.wl = (sizeof(ntest.w) / 2) - ntest.wl;
                break;
            }
            if (nrc == APR_INCOMPLETE) {
                ++ntest.nl;
                if (ntest.nl > 6) {
                    printf ("\n\nUnexpected utf8 sequence of >6 bytes;\n");
                    exit(255);
                }
                continue;
            }
            else {
                while (!(++ntest.n[ntest.nl - 1])) {
                    if (!(--ntest.nl))
                        break;
                }
            }
        } while (ntest.nl);

        do {
            inlen = wtest.wl;
            wtest.nl = sizeof(wtest.n);
            wrc = apr_conv_ucs2_to_utf8(wtest.w, &inlen, wtest.n, &wtest.nl);
            if (wrc == APR_SUCCESS) {
                wtest.nl = sizeof(wtest.n) - wtest.nl;
                break;
            }
            else {
                if (!(++wtest.w[wtest.wl - 1])) {
                    if (wtest.wl == 1)
                        ++wtest.wl;
                    else
                        ++wtest.w[0];

                    /* On the second pass, ensure lead word is incomplete */
                    do {
                        inlen = 1;
                        wtest.nl = sizeof(wtest.n);
                        if (apr_conv_ucs2_to_utf8(wtest.w, &inlen, wtest.n, &wtest.nl)
                                == APR_INCOMPLETE)
                            break;
                        if (!(++wtest.w[0])) {
                            wtest.wl = 0;
                            break;
                        }
                    } while (1);
                }
            }
        } while (wtest.wl);

        if (!ntest.nl && !wtest.wl)
            break;

        /* Identical? */
        if ((wtest.nl != ntest.nl)
         || (memcmp(wtest.n, ntest.n, ntest.nl) != 0)
         || (wtest.wl != ntest.wl)
         || (memcmp(ntest.w, wtest.w, wtest.wl * 2) != 0)) {
            printf ("\n\nMismatch of w/n conversion at;\n");
            displaynw(&ntest, &wtest);
            exit(255);
        }
        ++matches;

        while (!(++ntest.n[ntest.nl - 1])) {
            if (!(--ntest.nl))
                break;
        }

        if (!(++wtest.w[wtest.wl - 1])) {
            if (wtest.wl == 1)
                ++wtest.wl;
            else
                ++wtest.w[0];

            /* On the second pass, ensure lead word is incomplete */
            do {
                inlen = 1;
                wtest.nl = sizeof(wtest.n);
                if (apr_conv_ucs2_to_utf8(wtest.w, &inlen, wtest.n, &wtest.nl)
                        == APR_INCOMPLETE)
                    break;
                if (!(++wtest.w[0])) {
                    wtest.wl = 0;
                    break;
                }
            } while (1);
        }
    } while (wtest.wl || ntest.nl);

    printf ("\n\nutf8 and ucs2 sequences of %lu transformations matched OK.\n",
            matches);
}
Пример #11
0
svn_error_t *
svn_config__win_config_path(const char **folder, int system_path,
                            apr_pool_t *pool)
{
  /* ### Adding CSIDL_FLAG_CREATE here, because those folders really
     must exist.  I'm not too sure about the SHGFP_TYPE_CURRENT
     semancics, though; maybe we should use ..._DEFAULT instead? */
  const int csidl = ((system_path ? CSIDL_COMMON_APPDATA : CSIDL_APPDATA)
                     | CSIDL_FLAG_CREATE);

  int style;
  apr_status_t apr_err = apr_filepath_encoding(&style, pool);

  if (apr_err)
    return svn_error_wrap_apr(apr_err,
                              "Can't determine the native path encoding");

  if (style == APR_FILEPATH_ENCODING_UTF8)
    {
      WCHAR folder_ucs2[MAX_PATH];
      apr_size_t inwords, outbytes, outlength;
      char *folder_utf8;

      if (S_OK != SHGetFolderPathW(NULL, csidl, NULL, SHGFP_TYPE_CURRENT,
                                   folder_ucs2))
        goto no_folder_path;

      /* ### When mapping from UCS-2 to UTF-8, we need at most 3 bytes
             per wide char, plus extra space for the nul terminator. */
      inwords = lstrlenW(folder_ucs2);
      outbytes = outlength = 3 * (inwords + 1);
      folder_utf8 = apr_palloc(pool, outlength);

      apr_err = apr_conv_ucs2_to_utf8(folder_ucs2, &inwords,
                                      folder_utf8, &outbytes);
      if (!apr_err && (inwords > 0 || outbytes == 0))
        apr_err = APR_INCOMPLETE;
      if (apr_err)
        return svn_error_wrap_apr(apr_err,
                                  "Can't convert config path to UTF-8");

      /* Note that apr_conv_ucs2_to_utf8 does _not_ terminate the
         outgoing buffer. */
      folder_utf8[outlength - outbytes] = '\0';
      *folder = folder_utf8;
    }
  else if (style == APR_FILEPATH_ENCODING_LOCALE)
    {
      char folder_ansi[MAX_PATH];
      if (S_OK != SHGetFolderPathA(NULL, csidl, NULL, SHGFP_TYPE_CURRENT,
                                   folder_ansi))
        goto no_folder_path;
      SVN_ERR(svn_utf_cstring_to_utf8(folder, folder_ansi, pool));
    }
  else
    {
      /* There is no third option on Windows; we should never get here. */
      return svn_error_createf(APR_EINVAL, NULL,
                               "Unknown native path encoding (%d)", style);
    }

  *folder = svn_path_internal_style(*folder, pool);
  return SVN_NO_ERROR;

 no_folder_path:
  return svn_error_create(SVN_ERR_BAD_FILENAME, NULL,
                          (system_path
                           ? "Can't determine the system config path"
                           : "Can't determine the user's config path"));
}