Ejemplo n.º 1
0
AP_DECLARE(apr_status_t) ap_regkey_value_set(ap_regkey_t *key,
                                             const char *valuename,
                                             const char *value,
                                             apr_int32_t flags,
                                             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;
    apr_size_t size = strlen(value) + 1;
    DWORD type = (flags & AP_REGKEY_EXPAND) ? REG_EXPAND_SZ : REG_SZ;

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
        apr_size_t alloclen;
        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;

        wvallen = alloclen = size;
        wvalue = apr_palloc(pool, alloclen * 2);
        rv = apr_conv_utf8_to_ucs2(value, &size, wvalue, &wvallen);
        if (rv != APR_SUCCESS)
            return rv;
        else if (size)
            return APR_ENAMETOOLONG;

        /* The size is the number of wchars consumed by apr_conv_utf8_to_ucs2
         * converted to bytes; the trailing L'\0' continues to be counted.
         */
        size = (alloclen - wvallen) * 2;
        rc = RegSetValueExW(key->hkey, wvalname, 0, type,
                            (LPBYTE)wvalue, (DWORD)size);
        if (rc != ERROR_SUCCESS)
            return APR_FROM_OS_ERROR(rc);
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        rc = RegSetValueEx(key->hkey, valuename, 0, type, value, (DWORD)size);
        if (rc != ERROR_SUCCESS)
            return APR_FROM_OS_ERROR(rc);
    }
#endif
    return APR_SUCCESS;
}
Ejemplo n.º 2
0
AP_DECLARE(apr_status_t) ap_regkey_value_remove(const ap_regkey_t *key,
                                                const char *valuename,
                                                apr_pool_t *pool)
{
    LONG rc;

#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_status_t rv = apr_conv_utf8_to_ucs2(valuename, &valuelen, wvalname, &wvallen);
        if (rv != APR_SUCCESS)
            return rv;
        else if (valuelen)
            return APR_ENAMETOOLONG;
        rc = RegDeleteValueW(key->hkey, wvalname);
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        rc = RegDeleteValue(key->hkey, valuename);
    }
#endif
    if (rc != ERROR_SUCCESS) {
        return APR_FROM_OS_ERROR(rc);
    }
    return APR_SUCCESS;
}
Ejemplo n.º 3
0
AP_DECLARE(apr_status_t) ap_regkey_open(ap_regkey_t **newkey,
                                        const ap_regkey_t *parentkey,
                                        const char *keyname,
                                        apr_int32_t flags,
                                        apr_pool_t *pool)
{
    DWORD access = KEY_QUERY_VALUE;
    DWORD exists;
    HKEY hkey;
    LONG rc;

    if (flags & APR_READ)
        access |= KEY_READ;
    if (flags & APR_WRITE)
        access |= KEY_WRITE;

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
        apr_size_t keylen = strlen(keyname) + 1;
        apr_size_t wkeylen = 256;
        apr_wchar_t wkeyname[256];
        apr_status_t rv = apr_conv_utf8_to_ucs2(keyname, &keylen, wkeyname, &wkeylen);
        if (rv != APR_SUCCESS)
            return rv;
        else if (keylen)
            return APR_ENAMETOOLONG;

        if (flags & APR_CREATE)
            rc = RegCreateKeyExW(parentkey->hkey, wkeyname, 0, NULL, 0,
                                 access, NULL, &hkey, &exists);
        else
            rc = RegOpenKeyExW(parentkey->hkey, wkeyname, 0, access, &hkey);
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        if (flags & APR_CREATE)
            rc = RegCreateKeyEx(parentkey->hkey, keyname, 0, NULL, 0,
                                access, NULL, &hkey, &exists);
        else
            rc = RegOpenKeyEx(parentkey->hkey, keyname, 0, access, &hkey);
    }
#endif
    if (rc != ERROR_SUCCESS) {
        return APR_FROM_OS_ERROR(rc);
    }
    if ((flags & APR_EXCL) && (exists == REG_OPENED_EXISTING_KEY)) {
        RegCloseKey(hkey);
        return APR_EEXIST;
    }

    *newkey = apr_palloc(pool, sizeof(**newkey));
    (*newkey)->pool = pool;
    (*newkey)->hkey = hkey;
    apr_pool_cleanup_register((*newkey)->pool, (void *)(*newkey),
                              regkey_cleanup, apr_pool_cleanup_null);
    return APR_SUCCESS;
}
Ejemplo n.º 4
0
AP_DECLARE(apr_status_t) ap_regkey_value_raw_get(void **result,
                                                 apr_size_t *resultsize,
                                                 apr_int32_t *resulttype,
                                                 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;

#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_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, (LPDWORD)resulttype,
                              NULL, (LPDWORD)resultsize);
        if (rc != ERROR_SUCCESS) {
            return APR_FROM_OS_ERROR(rc);
        }

        /* Read value based on size query above */
        *result = apr_palloc(pool, *resultsize);
        rc = RegQueryValueExW(key->hkey, wvalname, 0, (LPDWORD)resulttype,
                             (LPBYTE)*result, (LPDWORD)resultsize);
    }
#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, (LPDWORD)resulttype,
                             NULL, (LPDWORD)resultsize);
        if (rc != ERROR_SUCCESS)
            return APR_FROM_OS_ERROR(rc);

        /* Read value based on size query above */
        *result = apr_palloc(pool, *resultsize);
        rc = RegQueryValueEx(key->hkey, valuename, 0, (LPDWORD)resulttype,
                             (LPBYTE)*result, (LPDWORD)resultsize);
        if (rc != ERROR_SUCCESS)
            return APR_FROM_OS_ERROR(rc);
    }
#endif
    if (rc != ERROR_SUCCESS) {
        return APR_FROM_OS_ERROR(rc);
    }

    return APR_SUCCESS;
}
Ejemplo n.º 5
0
Archivo: dso.c Proyecto: Ga-vin/apache
APR_DECLARE(apr_status_t) apr_dso_sym(apr_dso_handle_sym_t *ressym, 
                         struct apr_dso_handle_t *handle, 
                         const char *symname)
{
#ifdef _WIN32_WCE
    apr_size_t symlen = strlen(symname) + 1;
    apr_size_t wsymlen = 256;
    apr_wchar_t wsymname[256];
    apr_status_t rv;

    rv = apr_conv_utf8_to_ucs2(wsymname, &wsymlen, symname, &symlen);
    if (rv != APR_SUCCESS) {
        return rv;
    }
    else if (symlen) {
        return APR_ENAMETOOLONG;
    }

    *ressym = (apr_dso_handle_sym_t)GetProcAddressW(handle->handle, wsymname);
#else
    *ressym = (apr_dso_handle_sym_t)GetProcAddress(handle->handle, symname);
#endif
    if (!*ressym) {
        return apr_get_os_error();
    }
    return APR_SUCCESS;
}
Ejemplo n.º 6
0
AP_DECLARE(apr_status_t) ap_regkey_remove(const ap_regkey_t *parent,
                                          const char *keyname,
                                          apr_pool_t *pool)
{
    LONG rc;

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
        apr_size_t keylen = strlen(keyname) + 1;
        apr_size_t wkeylen = 256;
        apr_wchar_t wkeyname[256];
        apr_status_t rv = apr_conv_utf8_to_ucs2(keyname, &keylen, wkeyname, &wkeylen);
        if (rv != APR_SUCCESS)
            return rv;
        else if (keylen)
            return APR_ENAMETOOLONG;
        rc = RegDeleteKeyW(parent->hkey, wkeyname);
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        /* We need to determine if subkeys exist on Win9x, to provide
         * consistent behavior with NT, which returns access denied
         * if subkeys exist when attempting to delete a key.
         */
        DWORD subkeys;
        HKEY hkey;
        rc = RegOpenKeyEx(parent->hkey, keyname, 0, KEY_READ, &hkey);
        if (rc != ERROR_SUCCESS)
            return APR_FROM_OS_ERROR(rc);
        rc = RegQueryInfoKey(hkey, NULL, NULL, NULL, &subkeys, NULL, NULL,
                             NULL, NULL, NULL, NULL, NULL);
        RegCloseKey(hkey);
        if (rc != ERROR_SUCCESS)
            return APR_FROM_OS_ERROR(rc);
        else if (subkeys)
            return APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED);
        rc = RegDeleteKey(parent->hkey, keyname);
    }
#endif
    if (rc != ERROR_SUCCESS) {
        return APR_FROM_OS_ERROR(rc);
    }
    return APR_SUCCESS;
}
Ejemplo n.º 7
0
static
apr_status_t
TextConsoleWrite(
    void *opaque,
    const apr_byte_t *buffer,
    apr_size_t bytesToWrite,
    apr_size_t *bytesWritten
    )
{
    apr_status_t status;
    apr_size_t bytesRemaining = bytesToWrite;
    apr_size_t charsRemaining;
    apr_wchar_t outBuffer[256];
    const char *offset;
    DWORD charsToWrite;
    DWORD charsWritten;
    HANDLE console = opaque;

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

    do {
        // Convert the UTF-8 buffer to UCS-2
        charsRemaining = ARRAYSIZE(outBuffer);
        offset = (const char *)buffer + (bytesToWrite - bytesRemaining);
        status = apr_conv_utf8_to_ucs2(offset, &bytesRemaining, outBuffer, &charsRemaining);
        if (status == APR_EINVAL) {
            break;
        }

        // Write the UCS-2 buffer to the console
        charsToWrite = (DWORD)(ARRAYSIZE(outBuffer) - charsRemaining);
        if (WriteConsoleFullW(console, outBuffer, charsToWrite, &charsWritten)) {
            status = APR_SUCCESS;
        } else {
            status = apr_get_os_error();
        }
    } while (status == APR_SUCCESS && bytesRemaining > 0);

    if (bytesWritten != NULL) {
        *bytesWritten = bytesToWrite - bytesRemaining;
    }
    return status;
}
Ejemplo n.º 8
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_nrange(struct testval *p)
{
    struct testval f, l, s;
    apr_status_t rc;
    int success = 0;
    
    memcpy (&s, p, sizeof(s));
    ++s.nl;    
    
    do {
        apr_size_t nl = s.nl, wl = sizeof(s.w) / 2;
        rc = apr_conv_utf8_to_ucs2(s.n, &nl, s.w, &wl);
        s.wl = (sizeof(s.w) / 2) - wl;
        if (!nl && rc == APR_SUCCESS) {
            if (!success) {
                memcpy(&f, &s, sizeof(s));
                success = -1;
            }
            else {
                if (s.wl != l.wl 
                 || memcmp(s.w, l.w, (s.wl - 1) * 2) != 0
                 || s.w[s.wl - 1] != l.w[l.wl - 1] + 1) {
                    displaynw(&f, &l);
                    memcpy(&f, &s, sizeof(s));
                }
            }            
            memcpy(&l, &s, sizeof(s));
        }
        else {
            if (success) {
                displaynw(&f, &l);
                success = 0;
            }
            if (rc == APR_INCOMPLETE) {
                test_nrange(&s);
            }
        }
    } while (++s.n[s.nl - 1]);

    if (success) {
        displaynw(&f, &l);
        success = 0;
    }
}
Ejemplo n.º 9
0
/* Convert UTF8, a UTF-8 encoded string, to UCS2, a UCS-2 encoded
   string, using POOL for temporary allocations. */
static svn_error_t *
utf8_to_ucs2(WCHAR **ucs2, const char *utf8, apr_pool_t *pool)
{
  apr_size_t inbytes, outwords, outlength;
  apr_status_t apr_err;

  inbytes = lstrlenA(utf8);
  outwords = outlength = inbytes + 1; /* Include terminating null. */
  *ucs2 = apr_palloc(pool, outwords * sizeof(WCHAR));
  apr_err = apr_conv_utf8_to_ucs2(utf8, &inbytes, *ucs2, &outwords);

  if (!apr_err && (inbytes > 0 || outwords == 0))
    apr_err = APR_INCOMPLETE;
  if (apr_err)
    return svn_error_wrap_apr(apr_err, "Can't convert config path to UCS-2");

  /* Note that apr_conv_utf8_to_ucs2 does _not_ terminate the
     outgoing buffer. */
  (*ucs2)[outlength - outwords] = L'\0';
  return SVN_NO_ERROR;
}
Ejemplo n.º 10
0
AP_DECLARE(apr_status_t) ap_regkey_value_raw_set(ap_regkey_t *key,
                                                 const char *valuename,
                                                 const void *value,
                                                 apr_size_t valuesize,
                                                 apr_int32_t valuetype,
                                                 apr_pool_t *pool)
{
    LONG rc;

#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_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;

        rc = RegSetValueExW(key->hkey, wvalname, 0, valuetype,
                            (LPBYTE)value, (DWORD)valuesize);
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        rc = RegSetValueEx(key->hkey, valuename, 0, valuetype,
                            (LPBYTE)value, (DWORD)valuesize);
    }
#endif
    if (rc != ERROR_SUCCESS) {
        return APR_FROM_OS_ERROR(rc);
    }
    return APR_SUCCESS;
}
Ejemplo n.º 11
0
AP_DECLARE(apr_status_t) ap_regkey_value_array_set(ap_regkey_t *key,
                                                   const char *valuename,
                                                   int nelts,
                                                   const char * const * elts,
                                                   apr_pool_t *pool)
{
    /* Retrieve a registry string value, and explode any envvars
     * that the system has configured (e.g. %SystemRoot%/someapp.exe)
     */
    int i;
    const void *value;
    apr_size_t bufsize;

#if APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
        apr_status_t rv;
        apr_wchar_t *buf;
        apr_wchar_t *tmp;
        apr_size_t bufrem;

        bufsize = 1; /* For trailing second null */
        for (i = 0; i < nelts; ++i) {
            bufsize += strlen(elts[i]) + 1;
        }
        if (!nelts) {
            ++bufsize;
        }

        bufrem = bufsize;
        buf = apr_palloc(pool, bufsize * 2);
        tmp = buf;
        for (i = 0; i < nelts; ++i) {
            apr_size_t eltsize = strlen(elts[i]) + 1;
            apr_size_t size = eltsize;
            rv = apr_conv_utf8_to_ucs2(elts[i], &size, tmp, &bufrem);
            if (rv != APR_SUCCESS)
                return rv;
            else if (size)
                return APR_ENAMETOOLONG;
            tmp += eltsize;
        }
        if (!nelts) {
            --bufrem;
            (*tmp++) = L'\0';
        }
        --bufrem;
        *tmp = L'\0'; /* Trailing second null */

        bufsize = (bufsize - bufrem) * 2;
        value = (void*)buf;
    }
#endif /* APR_HAS_UNICODE_FS */
#if APR_HAS_ANSI_FS
    ELSE_WIN_OS_IS_ANSI
    {
        char *buf;
        char *tmp;

        bufsize = 1; /* For trailing second null */
        for (i = 0; i < nelts; ++i) {
            bufsize += strlen(elts[i]) + 1;
        }
        if (!nelts) {
            ++bufsize;
        }
        buf = apr_palloc(pool, bufsize);
        tmp = buf;
        for (i = 0; i < nelts; ++i) {
            apr_size_t len = strlen(elts[i]) + 1;
            memcpy(tmp, elts[i], len);
            tmp += len;
        }
        if (!nelts) {
            (*tmp++) = '\0';
        }
        *tmp = '\0'; /* Trailing second null */
        value = buf;
    }
#endif
    return ap_regkey_value_raw_set(key, valuename, value,
                                   bufsize, REG_MULTI_SZ, pool);
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
apr_status_t wsgi_utf8_to_unicode_path(apr_wchar_t* retstr,
                                       apr_size_t retlen, 
                                       const char* srcstr)
{
    /* TODO: The computations could preconvert the string to determine
     * the true size of the retstr, but that's a memory over speed
     * tradeoff that isn't appropriate this early in development.
     *
     * Allocate the maximum string length based on leading 4 
     * characters of \\?\ (allowing nearly unlimited path lengths) 
     * plus the trailing null, then transform /'s into \\'s since
     * the \\?\ form doesn't allow '/' path seperators.
     *
     * Note that the \\?\ form only works for local drive paths, and
     * \\?\UNC\ is needed UNC paths.
     */
    apr_size_t srcremains = strlen(srcstr) + 1;
    apr_wchar_t *t = retstr;
    apr_status_t rv;

    /* This is correct, we don't twist the filename if it is will
     * definately be shorter than 248 characters.  It merits some 
     * performance testing to see if this has any effect, but there
     * seem to be applications that get confused by the resulting
     * Unicode \\?\ style file names, especially if they use argv[0]
     * or call the Win32 API functions such as GetModuleName, etc.
     * Not every application is prepared to handle such names.
     * 
     * Note also this is shorter than MAX_PATH, as directory paths 
     * are actually limited to 248 characters. 
     *
     * Note that a utf-8 name can never result in more wide chars
     * than the original number of utf-8 narrow chars.
     */
    if (srcremains > 248) {
        if (srcstr[1] == ':' && (srcstr[2] == '/' || srcstr[2] == '\\')) {
            wcscpy (retstr, L"\\\\?\\");
            retlen -= 4;
            t += 4;
        }
        else if ((srcstr[0] == '/' || srcstr[0] == '\\')
              && (srcstr[1] == '/' || srcstr[1] == '\\')
              && (srcstr[2] != '?')) {
            /* Skip the slashes */
            srcstr += 2;
            srcremains -= 2;
            wcscpy (retstr, L"\\\\?\\UNC\\");
            retlen -= 8;
            t += 8;
        }
    }

    if (rv = apr_conv_utf8_to_ucs2(srcstr, &srcremains, t, &retlen)) {
        return (rv == APR_INCOMPLETE) ? APR_EINVAL : rv;
    }
    if (srcremains) {
        return APR_ENAMETOOLONG;
    }
    for (; *t; ++t)
        if (*t == L'/')
            *t = L'\\';
    return APR_SUCCESS;
}
Ejemplo n.º 14
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);
}