urlmon: Implemented canonicalization for URI fragments.
This commit is contained in:
parent
27ec56ea6b
commit
004e1be678
|
@ -3190,6 +3190,246 @@ static const uri_properties uri_tests[] = {
|
||||||
{URL_SCHEME_UNKNOWN,S_OK,FALSE},
|
{URL_SCHEME_UNKNOWN,S_OK,FALSE},
|
||||||
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
/* Forbidden characters in fragment aren't encoded for unknown schemes. */
|
||||||
|
{ "zip://www.winehq.org/tests/#Te<|>", 0, S_OK, FALSE,
|
||||||
|
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
|
||||||
|
Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
|
||||||
|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
|
||||||
|
TRUE,
|
||||||
|
{
|
||||||
|
{"zip://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"zip://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
|
||||||
|
{"winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"#Te<|>",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"zip://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
|
||||||
|
{"zip",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{Uri_HOST_DNS,S_OK,FALSE},
|
||||||
|
{0,S_FALSE,FALSE},
|
||||||
|
{URL_SCHEME_UNKNOWN,S_OK,FALSE},
|
||||||
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Forbidden characters in the fragment are percent encoded for known schemes. */
|
||||||
|
{ "http://www.winehq.org/tests/#Te<|>", 0, S_OK, FALSE,
|
||||||
|
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
|
||||||
|
Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
|
||||||
|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
|
||||||
|
TRUE,
|
||||||
|
{
|
||||||
|
{"http://www.winehq.org/tests/#Te%3C%7C%3E",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te%3C%7C%3E",S_OK,TRUE},
|
||||||
|
{"winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"#Te%3C%7C%3E",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
|
||||||
|
{"http",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{Uri_HOST_DNS,S_OK,FALSE},
|
||||||
|
{80,S_OK,FALSE},
|
||||||
|
{URL_SCHEME_HTTP,S_OK,FALSE},
|
||||||
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Forbidden characters aren't encoded in the fragment with this flag. */
|
||||||
|
{ "http://www.winehq.org/tests/#Te<|>", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
|
||||||
|
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
|
||||||
|
Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
|
||||||
|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
|
||||||
|
TRUE,
|
||||||
|
{
|
||||||
|
{"http://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
|
||||||
|
{"winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"#Te<|>",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
|
||||||
|
{"http",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{Uri_HOST_DNS,S_OK,FALSE},
|
||||||
|
{80,S_OK,FALSE},
|
||||||
|
{URL_SCHEME_HTTP,S_OK,FALSE},
|
||||||
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Forbidden characters aren't encoded in the fragment with this flag. */
|
||||||
|
{ "http://www.winehq.org/tests/#Te<|>", Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS, S_OK, FALSE,
|
||||||
|
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
|
||||||
|
Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
|
||||||
|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
|
||||||
|
TRUE,
|
||||||
|
{
|
||||||
|
{"http://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te<|>",S_OK,TRUE},
|
||||||
|
{"winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"#Te<|>",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te<|>",S_OK,FALSE},
|
||||||
|
{"http",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{Uri_HOST_DNS,S_OK,FALSE},
|
||||||
|
{80,S_OK,FALSE},
|
||||||
|
{URL_SCHEME_HTTP,S_OK,FALSE},
|
||||||
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Percent encoded, unreserved characters aren't decoded for known scheme types. */
|
||||||
|
{ "zip://www.winehq.org/tests/#Te%30%31%32", 0, S_OK, FALSE,
|
||||||
|
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
|
||||||
|
Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
|
||||||
|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_SCHEME,
|
||||||
|
TRUE,
|
||||||
|
{
|
||||||
|
{"zip://www.winehq.org/tests/#Te%30%31%32",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"zip://www.winehq.org/tests/#Te%30%31%32",S_OK,TRUE},
|
||||||
|
{"winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"#Te%30%31%32",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"zip://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
|
||||||
|
{"zip",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{Uri_HOST_DNS,S_OK,FALSE},
|
||||||
|
{0,S_FALSE,FALSE},
|
||||||
|
{URL_SCHEME_UNKNOWN,S_OK,FALSE},
|
||||||
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Percent encoded, unreserved characters are decoded for known schemes. */
|
||||||
|
{ "http://www.winehq.org/tests/#Te%30%31%32", 0, S_OK, FALSE,
|
||||||
|
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
|
||||||
|
Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
|
||||||
|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
|
||||||
|
TRUE,
|
||||||
|
{
|
||||||
|
{"http://www.winehq.org/tests/#Te012",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te012",S_OK,TRUE},
|
||||||
|
{"winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"#Te012",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
|
||||||
|
{"http",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{Uri_HOST_DNS,S_OK,FALSE},
|
||||||
|
{80,S_OK,FALSE},
|
||||||
|
{URL_SCHEME_HTTP,S_OK,FALSE},
|
||||||
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Percent encoded, unreserved characters are decoded even if NO_CANONICALIZE is set. */
|
||||||
|
{ "http://www.winehq.org/tests/#Te%30%31%32", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE,
|
||||||
|
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
|
||||||
|
Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
|
||||||
|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
|
||||||
|
TRUE,
|
||||||
|
{
|
||||||
|
{"http://www.winehq.org/tests/#Te012",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te012",S_OK,TRUE},
|
||||||
|
{"winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"#Te012",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
|
||||||
|
{"http",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{Uri_HOST_DNS,S_OK,FALSE},
|
||||||
|
{80,S_OK,FALSE},
|
||||||
|
{URL_SCHEME_HTTP,S_OK,FALSE},
|
||||||
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Percent encoded, unreserved characters aren't decoded when NO_DECODE_EXTRA is set. */
|
||||||
|
{ "http://www.winehq.org/tests/#Te%30%31%32", Uri_CREATE_NO_DECODE_EXTRA_INFO, S_OK, FALSE,
|
||||||
|
Uri_HAS_ABSOLUTE_URI|Uri_HAS_AUTHORITY|Uri_HAS_DISPLAY_URI|Uri_HAS_DOMAIN|Uri_HAS_FRAGMENT|
|
||||||
|
Uri_HAS_HOST|Uri_HAS_DOMAIN|Uri_HAS_PATH|Uri_HAS_PATH_AND_QUERY|Uri_HAS_RAW_URI|
|
||||||
|
Uri_HAS_SCHEME_NAME|Uri_HAS_HOST_TYPE|Uri_HAS_PORT|Uri_HAS_SCHEME,
|
||||||
|
TRUE,
|
||||||
|
{
|
||||||
|
{"http://www.winehq.org/tests/#Te%30%31%32",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te%30%31%32",S_OK,TRUE},
|
||||||
|
{"winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"#Te%30%31%32",S_OK,TRUE},
|
||||||
|
{"www.winehq.org",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"/tests/",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"http://www.winehq.org/tests/#Te%30%31%32",S_OK,FALSE},
|
||||||
|
{"http",S_OK,FALSE},
|
||||||
|
{"",S_FALSE,FALSE},
|
||||||
|
{"",S_FALSE,FALSE}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{Uri_HOST_DNS,S_OK,FALSE},
|
||||||
|
{80,S_OK,FALSE},
|
||||||
|
{URL_SCHEME_HTTP,S_OK,FALSE},
|
||||||
|
{URLZONE_INVALID,E_NOTIMPL,FALSE},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,9 @@ typedef struct {
|
||||||
|
|
||||||
INT query_start;
|
INT query_start;
|
||||||
DWORD query_len;
|
DWORD query_len;
|
||||||
|
|
||||||
|
INT fragment_start;
|
||||||
|
DWORD fragment_len;
|
||||||
} Uri;
|
} Uri;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -2749,6 +2752,56 @@ static BOOL canonicalize_query(const parse_data *data, Uri *uri, DWORD flags, BO
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL canonicalize_fragment(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
|
||||||
|
const WCHAR *ptr, *end;
|
||||||
|
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
|
||||||
|
|
||||||
|
if(!data->fragment) {
|
||||||
|
uri->fragment_start = -1;
|
||||||
|
uri->fragment_len = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uri->fragment_start = uri->canon_len;
|
||||||
|
|
||||||
|
end = data->fragment + data->fragment_len;
|
||||||
|
for(ptr = data->fragment; ptr < end; ++ptr) {
|
||||||
|
if(*ptr == '%') {
|
||||||
|
if(known_scheme && !(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
|
||||||
|
WCHAR val = decode_pct_val(ptr);
|
||||||
|
if(is_unreserved(val)) {
|
||||||
|
if(!computeOnly)
|
||||||
|
uri->canon_uri[uri->canon_len] = val;
|
||||||
|
++uri->canon_len;
|
||||||
|
|
||||||
|
ptr += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(known_scheme && !is_unreserved(*ptr) && !is_reserved(*ptr)) {
|
||||||
|
if(!(flags & Uri_CREATE_NO_ENCODE_FORBIDDEN_CHARACTERS) &&
|
||||||
|
!(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) {
|
||||||
|
if(!computeOnly)
|
||||||
|
pct_encode_val(*ptr, uri->canon_uri+uri->canon_len);
|
||||||
|
uri->canon_len += 3;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!computeOnly)
|
||||||
|
uri->canon_uri[uri->canon_len] = *ptr;
|
||||||
|
++uri->canon_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uri->fragment_len = uri->canon_len - uri->fragment_start;
|
||||||
|
|
||||||
|
if(!computeOnly)
|
||||||
|
TRACE("(%p %p %x %d): Canonicalized fragment %s len=%d\n", data, uri, flags,
|
||||||
|
computeOnly, debugstr_wn(uri->canon_uri+uri->fragment_start, uri->fragment_len),
|
||||||
|
uri->fragment_len);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Canonicalizes the scheme information specified in the parse_data using the specified flags. */
|
/* Canonicalizes the scheme information specified in the parse_data using the specified flags. */
|
||||||
static BOOL canonicalize_scheme(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
|
static BOOL canonicalize_scheme(const parse_data *data, Uri *uri, DWORD flags, BOOL computeOnly) {
|
||||||
uri->scheme_start = -1;
|
uri->scheme_start = -1;
|
||||||
|
@ -2816,6 +2869,11 @@ static int compute_canonicalized_length(const parse_data *data, DWORD flags) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!canonicalize_fragment(data, &uri, flags, TRUE)) {
|
||||||
|
ERR("(%p %x): Failed to compute fragment length.\n", data, flags);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("(%p %x): Finished computing canonicalized URI length. length=%d\n", data, flags, uri.canon_len);
|
TRACE("(%p %x): Finished computing canonicalized URI length. length=%d\n", data, flags, uri.canon_len);
|
||||||
|
|
||||||
return uri.canon_len;
|
return uri.canon_len;
|
||||||
|
@ -2869,6 +2927,12 @@ static HRESULT canonicalize_uri(const parse_data *data, Uri *uri, DWORD flags) {
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!canonicalize_fragment(data, uri, flags, FALSE)) {
|
||||||
|
ERR("(%p %p %x): Unable to canonicalize fragment of the URI.\n",
|
||||||
|
data, uri, flags);
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
/* There's a possibility we didn't use all the space we allocated
|
/* There's a possibility we didn't use all the space we allocated
|
||||||
* earlier.
|
* earlier.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue