15 #include <mach-o/dyld.h>
17 #include <CoreServices/CoreServices.h>
18 #include "VuoUrlParser.h"
25 "description" :
"Uniform Resource Locator.",
26 "keywords" : [
"link" ],
29 "CoreServices.framework",
44 const char *textString =
"";
45 if (json_object_get_type(js) == json_type_string)
46 textString = json_object_get_string(js);
50 url = strdup(textString);
64 return json_object_new_string(
"");
66 return json_object_new_string(value);
76 char *summary = strdup(t);
91 struct http_parser_url parsedUrl;
92 if (http_parser_parse_url(url, strlen(url),
false, &parsedUrl))
95 if (strncmp(url,
"data:", 5) == 0)
119 if (parsedUrl.field_set & (1 << UF_SCHEMA))
127 if (parsedUrl.field_set & (1 << UF_USERINFO))
135 if (parsedUrl.field_set & (1 << UF_HOST))
143 if (parsedUrl.field_set & (1 << UF_PORT))
145 *port = parsedUrl.port;
150 if (strcmp(*scheme,
"http") == 0)
152 else if (strcmp(*scheme,
"https") == 0)
159 if (parsedUrl.field_set & (1 << UF_PATH))
167 if (parsedUrl.field_set & (1 << UF_QUERY))
175 if (parsedUrl.field_set & (1 << UF_FRAGMENT))
176 *fragment =
VuoText_makeWithMaxLength(url + parsedUrl.field_data[UF_FRAGMENT].off, parsedUrl.field_data[UF_FRAGMENT].len);
206 if (separatorIndex < length)
209 fileAndExtension = NULL;
256 const char *urlWithSchemePattern =
"^[a-zA-Z][a-zA-Z0-9+-\\.]+:";
257 regex_t urlWithSchemeRegExp;
259 regmatch_t pmatch[0];
261 regcomp(&urlWithSchemeRegExp, urlWithSchemePattern, REG_EXTENDED);
262 bool matchFound = !regexec(&urlWithSchemeRegExp, url, nmatch, pmatch, 0);
263 regfree(&urlWithSchemeRegExp);
273 return ((strlen(url) >= 1) && (url[0] ==
'/'));
281 return ((strlen(url) >= 1) && (url[0] ==
'~'));
300 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
301 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
302 '"',
'$',
'&',
'+',
',',
':',
';',
'=',
'?',
'@',
'#',
' ',
313 unsigned long inLength = strlen(path);
314 unsigned long escapedLength = 0;
315 for (
unsigned long i = 0; i < inLength; ++i)
328 char *escapedUrl = (
char *)malloc(escapedLength + 1);
329 unsigned long outIndex = 0;
330 const char *hexCharSet =
"0123456789ABCDEF";
331 for (
unsigned long inIndex = 0; inIndex < inLength; ++inIndex)
333 unsigned char c = path[inIndex];
334 bool foundEscape =
false;
338 escapedUrl[outIndex++] =
'%';
339 escapedUrl[outIndex++] = hexCharSet[c >> 4];
340 escapedUrl[outIndex++] = hexCharSet[c & 0x0f];
348 if (inIndex+2 < inLength)
349 if (c == 0xea && (
unsigned char)path[inIndex+1] == 0x9e && (
unsigned char)path[inIndex+2] == 0x89)
351 escapedUrl[outIndex++] =
'%';
352 escapedUrl[outIndex++] = hexCharSet[
':' >> 4];
353 escapedUrl[outIndex++] = hexCharSet[
':' & 0x0f];
359 escapedUrl[outIndex++] = c;
361 escapedUrl[outIndex] = 0;
375 unsigned long inLength = strlen(url);
376 unsigned long escapedLength = 0;
377 for (
unsigned long i = 0; i < inLength; ++i)
379 if ((
unsigned char)url[i] > 0x7f)
385 char *escapedUrl = (
char *)malloc(escapedLength + 1);
386 unsigned long outIndex = 0;
387 const char *hexCharSet =
"0123456789ABCDEF";
388 for (
unsigned long inIndex = 0; inIndex < inLength; ++inIndex)
390 unsigned char c = url[inIndex];
393 escapedUrl[outIndex++] =
'%';
394 escapedUrl[outIndex++] = hexCharSet[c >> 4];
395 escapedUrl[outIndex++] = hexCharSet[c & 0x0f];
398 escapedUrl[outIndex++] = c;
400 escapedUrl[outIndex] = 0;
441 size_t urlLen = strlen(url);
442 size_t spaceCount = 0;
443 for (
size_t i = 0; i < urlLen; ++i)
448 resolvedUrl = (
char *)malloc(strlen(url) + spaceCount*2);
450 for (
size_t i = 0; i < urlLen; ++i)
453 resolvedUrl[p++] =
'%';
454 resolvedUrl[p++] =
'2';
455 resolvedUrl[p++] =
'0';
458 resolvedUrl[p++] = url[i];
462 resolvedUrl = strdup(url);
468 char *filePath = (
char *)url;
475 if (access(filePath, 0) != 0)
477 char userTempDir[PATH_MAX];
478 size_t userTempDirLen;
479 if ((userTempDirLen = confstr(_CS_DARWIN_USER_TEMP_DIR, userTempDir, PATH_MAX)) > 0)
481 size_t filePathLen = strlen(filePath);
482 size_t mallocSize = userTempDirLen + filePathLen + 1;
483 char *privateFilePath = (
char *)malloc(mallocSize);
484 strlcpy(privateFilePath, userTempDir, mallocSize);
485 strlcat(privateFilePath, filePath + 4, mallocSize);
486 filePath = privateFilePath;
491 char *realPath = realpath(filePath, NULL);
501 resolvedUrl = (
char *)malloc(mallocSize);
503 strlcat(resolvedUrl, escapedPath, mallocSize);
514 char *homeDir = getenv(
"HOME");
515 VuoText paths[2] = { homeDir, url+1 };
521 char *realPath = realpath(absolutePath, NULL);
530 resolvedUrl = (
char *)malloc(mallocSize);
532 strlcat(resolvedUrl, escapedPath, mallocSize);
540 resolvedUrl = (
char *)malloc(mallocSize);
542 strlcat(resolvedUrl, url, mallocSize);
550 bool compositionIsExportedApp =
false;
556 if (!strcmp(currentWorkingDir,
"/"))
559 char rawExecutablePath[PATH_MAX+1];
560 uint32_t size =
sizeof(rawExecutablePath);
561 _NSGetExecutablePath(rawExecutablePath, &size);
563 char cleanedExecutablePath[PATH_MAX+1];
564 realpath(rawExecutablePath, cleanedExecutablePath);
567 size_t pathSize = PATH_MAX + 1;
568 char executableDir[pathSize];
569 strlcpy(executableDir, dirname(cleanedExecutablePath), pathSize);
571 const char *resourcesPathFromExecutable =
"/../Resources";
572 pathSize = strlen(executableDir) + strlen(resourcesPathFromExecutable) + 1;
573 char rawResourcesPath[pathSize];
574 strlcpy(rawResourcesPath, executableDir, pathSize);
575 strlcat(rawResourcesPath, resourcesPathFromExecutable, pathSize);
577 char cleanedResourcesPath[PATH_MAX+1];
578 realpath(rawResourcesPath, cleanedResourcesPath);
582 if (access(cleanedResourcesPath, 0) == 0)
584 compositionIsExportedApp =
true;
588 char *homeDir = getenv(
"HOME");
589 const char *desktop =
"/Desktop/";
590 size_t mallocSize = strlen(homeDir) + strlen(desktop) + strlen(url) + 1;
591 absolutePath = (
char *)malloc(mallocSize);
592 strlcpy(absolutePath, homeDir, mallocSize);
593 strlcat(absolutePath, desktop, mallocSize);
594 strlcat(absolutePath, url, mallocSize);
598 size_t mallocSize = strlen(cleanedResourcesPath) + strlen(
"/") + strlen(url) + 1;
599 absolutePath = (
char *)malloc(mallocSize);
600 strlcpy(absolutePath, cleanedResourcesPath, mallocSize);
601 strlcat(absolutePath,
"/", mallocSize);
602 strlcat(absolutePath, url, mallocSize);
608 if (!compositionIsExportedApp)
610 size_t mallocSize = strlen(currentWorkingDir) + strlen(
"/") + strlen(url) + 1;
611 absolutePath = (
char *)malloc(mallocSize);
612 strlcpy(absolutePath, currentWorkingDir, mallocSize);
613 strlcat(absolutePath,
"/", mallocSize);
614 strlcat(absolutePath, url, mallocSize);
617 char *realPath = realpath(absolutePath, NULL);
627 resolvedUrl = (
char *)malloc(mallocSize);
629 strlcat(resolvedUrl, escapedPath, mallocSize);
633 size_t lastIndex = strlen(resolvedUrl) - 1;
634 if (resolvedUrl[lastIndex] ==
'/')
635 resolvedUrl[lastIndex] = 0;
653 unsigned long inLength = strlen(url);
654 char *unescapedUrl = (
char *)malloc(inLength + 1);
655 unsigned long outIndex = 0;
656 for (
unsigned long inIndex = 0; inIndex < inLength; ++inIndex, ++outIndex)
658 char c = url[inIndex];
661 if (inIndex + 2 >= inLength)
663 char highNibbleASCII = url[++inIndex];
664 char lowNibbleASCII = url[++inIndex];
668 unescapedUrl[outIndex] = c;
670 unescapedUrl[outIndex] = 0;
674 return unescapedUrlVT;
692 unsigned long inLength = strlen(url);
694 char *unescapedUrl = (
char *)malloc(inLength*3 + 1);
695 unsigned long outIndex = 0;
696 for (
unsigned long inIndex = fileSchemeLength; inIndex < inLength; ++inIndex, ++outIndex)
698 char c = url[inIndex];
701 char highNibbleASCII = url[++inIndex];
702 char lowNibbleASCII = url[++inIndex];
706 unescapedUrl[outIndex] = c;
712 if (unescapedUrl[outIndex] ==
':')
714 unescapedUrl[outIndex++] = 0xea;
715 unescapedUrl[outIndex++] = 0x9e;
716 unescapedUrl[outIndex] = 0x89;
719 unescapedUrl[outIndex] = 0;
724 return unescapedUrlVT;
749 CFStringRef urlCFS = CFStringCreateWithCString(NULL, url, kCFStringEncodingUTF8);
750 CFURLRef cfurl = CFURLCreateWithString(NULL, urlCFS, NULL);
754 VUserLog(
"Error: Couldn't check '%s': Invalid URL.", url);
758 LSItemInfoRecord outItemInfo;
759 OSStatus ret = LSCopyItemInfoForURL(cfurl, kLSRequestAllFlags, &outItemInfo);
764 VUserLog(
"Error: Couldn't check '%s': %s", url, errorString);
768 return outItemInfo.flags & kLSItemInfoIsPackage;
776 char* fileSuffix = strrchr(filename,
'.');
777 char* curExtension = fileSuffix != NULL ? strdup(fileSuffix+1) : NULL;
779 if(curExtension != NULL)
780 for(
char *p = &curExtension[0]; *p; p++) *p = tolower(*p);
783 for (
int i = 0; i < json_object_array_length(validExtensions); ++i)
785 if (curExtension != NULL && strcmp(curExtension, json_object_get_string(json_object_array_get_idx(validExtensions, i))) == 0)
794 const char *chosenExtension = json_object_get_string(json_object_array_get_idx(validExtensions, 0));
795 size_t buf_size = strlen(filename) + strlen(chosenExtension) + 2;
796 char* newfilepath = (
char*)malloc(buf_size *
sizeof(
char));
797 snprintf(newfilepath, buf_size,
"%s.%s", filename, chosenExtension);