Commit c8679593 authored by Damien Fouilleul's avatar Damien Fouilleul

activex: UrlCombine() API is actually buggy, use replacement API already...

activex: UrlCombine() API is actually buggy, use replacement API already present on mozilla (needs loads of testing)
parent 02e15f16
...@@ -639,24 +639,19 @@ HRESULT VLCPlugin::getVLC(libvlc_instance_t** pp_libvlc) ...@@ -639,24 +639,19 @@ HRESULT VLCPlugin::getVLC(libvlc_instance_t** pp_libvlc)
if( SysStringLen(_bstr_baseurl) > 0 ) if( SysStringLen(_bstr_baseurl) > 0 )
{ {
DWORD len = INTERNET_MAX_URL_LENGTH; /*
LPOLESTR abs_url = (LPOLESTR)CoTaskMemAlloc(sizeof(OLECHAR)*len); ** if the MRL a relative URL, we should end up with an absolute URL
*/
LPWSTR abs_url = CombineURL(_bstr_baseurl, _bstr_mrl);
if( NULL != abs_url ) if( NULL != abs_url )
{ {
/* psz_mrl = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
** if the MRL a relative URL, we should end up with an absolute URL
*/
if( SUCCEEDED(UrlCombineW(_bstr_baseurl, _bstr_mrl, abs_url, &len,
URL_ESCAPE_UNSAFE|URL_PLUGGABLE_PROTOCOL)) )
{
psz_mrl = CStrFromBSTR(CP_UTF8, abs_url);
}
else
{
psz_mrl = CStrFromBSTR(CP_UTF8, _bstr_mrl);
}
CoTaskMemFree(abs_url); CoTaskMemFree(abs_url);
} }
else
{
psz_mrl = CStrFromBSTR(CP_UTF8, _bstr_mrl);
}
} }
else else
{ {
......
...@@ -22,24 +22,26 @@ ...@@ -22,24 +22,26 @@
#include "utils.h" #include "utils.h"
#include <wchar.h>
#include <wctype.h>
/* /*
** conversion facilities ** conversion facilities
*/ */
using namespace std; using namespace std;
char *CStrFromBSTR(UINT codePage, BSTR bstr) char *CStrFromWSTR(UINT codePage, LPCWSTR wstr, UINT len)
{ {
UINT len = SysStringLen(bstr);
if( len > 0 ) if( len > 0 )
{ {
size_t mblen = WideCharToMultiByte(codePage, size_t mblen = WideCharToMultiByte(codePage,
0, bstr, len, NULL, 0, NULL, NULL); 0, wstr, len, NULL, 0, NULL, NULL);
if( mblen > 0 ) if( mblen > 0 )
{ {
char *buffer = (char *)CoTaskMemAlloc(mblen+1); char *buffer = (char *)CoTaskMemAlloc(mblen+1);
ZeroMemory(buffer, mblen+1); ZeroMemory(buffer, mblen+1);
if( WideCharToMultiByte(codePage, 0, bstr, len, buffer, mblen, NULL, NULL) ) if( WideCharToMultiByte(codePage, 0, wstr, len, buffer, mblen, NULL, NULL) )
{ {
buffer[mblen] = '\0'; buffer[mblen] = '\0';
return buffer; return buffer;
...@@ -49,6 +51,11 @@ char *CStrFromBSTR(UINT codePage, BSTR bstr) ...@@ -49,6 +51,11 @@ char *CStrFromBSTR(UINT codePage, BSTR bstr)
return NULL; return NULL;
}; };
char *CStrFromBSTR(UINT codePage, BSTR bstr)
{
return CStrFromWSTR(codePage, bstr, SysStringLen(bstr));
};
BSTR BSTRFromCStr(UINT codePage, LPCSTR s) BSTR BSTRFromCStr(UINT codePage, LPCSTR s)
{ {
int wideLen = MultiByteToWideChar(codePage, 0, s, -1, NULL, 0); int wideLen = MultiByteToWideChar(codePage, 0, s, -1, NULL, 0);
...@@ -156,7 +163,7 @@ HDC CreateDevDC(DVTARGETDEVICE *ptd) ...@@ -156,7 +163,7 @@ HDC CreateDevDC(DVTARGETDEVICE *ptd)
hdc = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, lpDevMode); hdc = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, lpDevMode);
} }
return hdc; return hdc;
}; };
#define HIMETRIC_PER_INCH 2540 #define HIMETRIC_PER_INCH 2540
...@@ -184,3 +191,156 @@ void HimetricFromDP(HDC hdc, LPPOINT pt, int count) ...@@ -184,3 +191,156 @@ void HimetricFromDP(HDC hdc, LPPOINT pt, int count)
++pt; ++pt;
} }
}; };
LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url)
{
if( NULL != url )
{
// check whether URL is already absolute
const wchar_t *end=wcschr(url, L':');
if( (NULL != end) && (end != url) )
{
// validate protocol header
const wchar_t *start = url;
while( start != end ) {
wchar_t c = towlower(*start);
if( (c < L'a') || (c > L'z') )
// not a valid protocol header, assume relative URL
goto relativeurl;
++start;
}
/* we have a protocol header, therefore URL is absolute */
UINT len = wcslen(url);
wchar_t *href = (LPWSTR)CoTaskMemAlloc((len+1)*sizeof(wchar_t));
if( href )
{
memcpy(href, url, len*sizeof(wchar_t));
href[len] = L'\0';
}
return href;
}
relativeurl:
if( baseUrl )
{
size_t baseLen = wcslen(baseUrl);
wchar_t *href = (LPWSTR)CoTaskMemAlloc((baseLen+wcslen(url)+1)*sizeof(wchar_t));
if( href )
{
/* prepend base URL */
wcscpy(href, baseUrl);
/*
** relative url could be empty,
** in which case return base URL
*/
if( L'\0' == *url )
return href;
/*
** locate pathname part of base URL
*/
/* skip over protocol part */
wchar_t *pathstart = wcschr(href, L':');
wchar_t *pathend;
if( pathstart )
{
if( L'/' == *(++pathstart) )
{
if( L'/' == *(++pathstart) )
{
++pathstart;
}
}
/* skip over host part */
pathstart = wcschr(pathstart, L'/');
pathend = href+baseLen;
if( ! pathstart )
{
// no path, add a / past end of url (over '\0')
pathstart = pathend;
*pathstart = L'/';
}
}
else
{
/* baseURL is just a UNIX file path */
if( L'/' != *href )
{
/* baseURL is not an absolute path */
return NULL;
}
pathstart = href;
pathend = href+baseLen;
}
/* relative URL made of an absolute path ? */
if( L'/' == *url )
{
/* replace path completely */
wcscpy(pathstart, url);
return href;
}
/* find last path component and replace it */
while( L'/' != *pathend )
--pathend;
/*
** if relative url path starts with one or more './' or '../',
** factor them out of href so that we return a
** normalized URL
*/
while( pathend > pathstart )
{
const wchar_t *p = url;
if( L'.' != *p )
break;
++p;
if( L'\0' == *p )
{
/* relative url is just '.' */
url = p;
break;
}
if( L'/' == *p )
{
/* relative url starts with './' */
url = ++p;
continue;
}
if( L'.' != *p )
break;
++p;
if( L'\0' == *p )
{
/* relative url is '..' */
}
else
{
if( L'/' != *p )
break;
/* relative url starts with '../' */
++p;
}
url = p;
do
{
--pathend;
}
while( L'/' != *pathend );
}
/* skip over '/' separator */
++pathend;
/* concatenate remaining base URL and relative URL */
wcscpy(pathend, url);
}
return href;
}
}
return NULL;
}
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <vector> #include <vector>
// utilities // utilities
extern char *CStrFromWSTR(UINT codePage, LPCWSTR wstr, UINT len);
extern char *CStrFromBSTR(UINT codePage, BSTR bstr); extern char *CStrFromBSTR(UINT codePage, BSTR bstr);
extern BSTR BSTRFromCStr(UINT codePage, LPCSTR s); extern BSTR BSTRFromCStr(UINT codePage, LPCSTR s);
...@@ -41,6 +42,9 @@ extern HDC CreateDevDC(DVTARGETDEVICE *ptd); ...@@ -41,6 +42,9 @@ extern HDC CreateDevDC(DVTARGETDEVICE *ptd);
extern void DPFromHimetric(HDC hdc, LPPOINT pt, int count); extern void DPFromHimetric(HDC hdc, LPPOINT pt, int count);
extern void HimetricFromDP(HDC hdc, LPPOINT pt, int count); extern void HimetricFromDP(HDC hdc, LPPOINT pt, int count);
// URL
extern LPWSTR CombineURL(LPCWSTR baseUrl, LPCWSTR url);
/**************************************************************************************************/ /**************************************************************************************************/
/* this function object is used to dereference the iterator into a value */ /* this function object is used to dereference the iterator into a value */
......
...@@ -1500,24 +1500,19 @@ STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* ite ...@@ -1500,24 +1500,19 @@ STDMETHODIMP VLCPlaylist::add(BSTR uri, VARIANT name, VARIANT options, long* ite
char *psz_uri = NULL; char *psz_uri = NULL;
if( SysStringLen(_p_instance->getBaseURL()) > 0 ) if( SysStringLen(_p_instance->getBaseURL()) > 0 )
{ {
DWORD len = INTERNET_MAX_URL_LENGTH; /*
LPOLESTR abs_url = (LPOLESTR)CoTaskMemAlloc(sizeof(OLECHAR)*len); ** if the MRL a relative URL, we should end up with an absolute URL
*/
LPWSTR abs_url = CombineURL(_p_instance->getBaseURL(), uri);
if( NULL != abs_url ) if( NULL != abs_url )
{ {
/* psz_uri = CStrFromWSTR(CP_UTF8, abs_url, wcslen(abs_url));
** if the MRL a relative URL, we should end up with an absolute URL
*/
if( SUCCEEDED(UrlCombineW(_p_instance->getBaseURL(), uri, abs_url, &len,
URL_ESCAPE_UNSAFE|URL_PLUGGABLE_PROTOCOL)) )
{
psz_uri = CStrFromBSTR(CP_UTF8, abs_url);
}
else
{
psz_uri = CStrFromBSTR(CP_UTF8, uri);
}
CoTaskMemFree(abs_url); CoTaskMemFree(abs_url);
} }
else
{
psz_uri = CStrFromBSTR(CP_UTF8, uri);
}
} }
else else
{ {
......
...@@ -1313,10 +1313,11 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP ...@@ -1313,10 +1313,11 @@ RuntimeNPObject::InvokeResult LibvlcPlaylistNPObject::invoke(int index, const NP
if( s ) if( s )
{ {
url = p_plugin->getAbsoluteURL(s); url = p_plugin->getAbsoluteURL(s);
delete s; if( url )
if( ! url ) delete s;
// what happened ? else
return INVOKERESULT_GENERIC_ERROR; // problem with combining url, use argument
url = s;
} }
else else
return INVOKERESULT_OUT_OF_MEMORY; return INVOKERESULT_OUT_OF_MEMORY;
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "control/npovlc.h" #include "control/npovlc.h"
#include "control/npolibvlc.h" #include "control/npolibvlc.h"
#include <ctype.h>
/***************************************************************************** /*****************************************************************************
* VlcPlugin constructor and destructor * VlcPlugin constructor and destructor
*****************************************************************************/ *****************************************************************************/
...@@ -226,7 +228,8 @@ NPError VlcPlugin::init(int argc, char* const argn[], char* const argv[]) ...@@ -226,7 +228,8 @@ NPError VlcPlugin::init(int argc, char* const argn[], char* const argv[])
if( psz_target ) if( psz_target )
{ {
// get absolute URL from src // get absolute URL from src
psz_target = getAbsoluteURL(psz_target); char *psz_absurl = getAbsoluteURL(psz_target);
psz_target = psz_absurl ? psz_absurl : strdup(psz_target);
} }
/* assign plugin script root class */ /* assign plugin script root class */
...@@ -304,16 +307,18 @@ char *VlcPlugin::getAbsoluteURL(const char *url) ...@@ -304,16 +307,18 @@ char *VlcPlugin::getAbsoluteURL(const char *url)
// validate protocol header // validate protocol header
const char *start = url; const char *start = url;
while( start != end ) { while( start != end ) {
char c = *start | 0x20; char c = tolower(*start);
if( (c < 'a') || (c > 'z') ) if( (c < 'a') || (c > 'z') )
// not valid protocol header, assume relative URL // not valid protocol header, assume relative URL
break; goto relativeurl;
++start; ++start;
} }
/* we have a protocol header, therefore URL is absolute */ /* we have a protocol header, therefore URL is absolute */
return strdup(url); return strdup(url);
} }
relativeurl:
if( psz_baseURL ) if( psz_baseURL )
{ {
size_t baseLen = strlen(psz_baseURL); size_t baseLen = strlen(psz_baseURL);
...@@ -337,31 +342,36 @@ char *VlcPlugin::getAbsoluteURL(const char *url) ...@@ -337,31 +342,36 @@ char *VlcPlugin::getAbsoluteURL(const char *url)
/* skip over protocol part */ /* skip over protocol part */
char *pathstart = strchr(href, ':'); char *pathstart = strchr(href, ':');
char *pathend; char *pathend;
if( pathstart ) if( pathstart )
{ {
if( '/' == *(++pathstart) ) if( '/' == *(++pathstart) )
{ {
if( '/' == *(++pathstart) ) if( '/' == *(++pathstart) )
{ {
++pathstart; ++pathstart;
} }
} }
/* skip over host part */ /* skip over host part */
pathstart = strchr(pathstart, '/'); pathstart = strchr(pathstart, '/');
pathend = href+baseLen; pathend = href+baseLen;
if( ! pathstart ) if( ! pathstart )
{ {
// no path, add a / past end of url (over '\0') // no path, add a / past end of url (over '\0')
pathstart = pathend; pathstart = pathend;
*pathstart = '/'; *pathstart = '/';
} }
} }
else else
{ {
/* baseURL is just a path */ /* baseURL is just a UNIX path */
pathstart = href; if( '/' != *href )
pathend = href+baseLen; {
} /* baseURL is not an absolute path */
return NULL;
}
pathstart = href;
pathend = href+baseLen;
}
/* relative URL made of an absolute path ? */ /* relative URL made of an absolute path ? */
if( '/' == *url ) if( '/' == *url )
...@@ -372,7 +382,8 @@ char *VlcPlugin::getAbsoluteURL(const char *url) ...@@ -372,7 +382,8 @@ char *VlcPlugin::getAbsoluteURL(const char *url)
} }
/* find last path component and replace it */ /* find last path component and replace it */
while( '/' != *pathend) --pathend; while( '/' != *pathend)
--pathend;
/* /*
** if relative url path starts with one or more '../', ** if relative url path starts with one or more '../',
...@@ -385,17 +396,42 @@ char *VlcPlugin::getAbsoluteURL(const char *url) ...@@ -385,17 +396,42 @@ char *VlcPlugin::getAbsoluteURL(const char *url)
if( '.' != *p ) if( '.' != *p )
break; break;
++p; ++p;
if( '.' != *p ) if( '\0' == *p )
{
/* relative url is just '.' */
url = p;
break; break;
++p; }
if( '/' != *p ) if( '/' == *p )
{
/* relative url starts with './' */
url = ++p;
continue;
}
if( '.' != *p )
break; break;
++p; if( '\0' == *p )
{
/* relative url is '..' */
}
else
{
if( '/' != *p )
break;
/* relative url starts with '../' */
++p;
}
url = p; url = p;
while( '/' != *pathend ) --pathend; do
{
--pathend;
}
while( '/' != *pathend );
} }
/* skip over '/' separator */
++pathend;
/* concatenate remaining base URL and relative URL */ /* concatenate remaining base URL and relative URL */
strcpy(pathend+1, url); strcpy(pathend, url);
} }
return href; return href;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment