OLD | NEW |
1 /** | 1 /** |
2 * uri.c: set of generic URI related routines | 2 * uri.c: set of generic URI related routines |
3 * | 3 * |
4 * Reference: RFCs 3986, 2732 and 2373 | 4 * Reference: RFCs 3986, 2732 and 2373 |
5 * | 5 * |
6 * See Copyright for the status of this software. | 6 * See Copyright for the status of this software. |
7 * | 7 * |
8 * daniel@veillard.com | 8 * daniel@veillard.com |
9 */ | 9 */ |
10 | 10 |
11 #define IN_LIBXML | 11 #define IN_LIBXML |
12 #include "libxml.h" | 12 #include "libxml.h" |
13 | 13 |
14 #include <string.h> | 14 #include <string.h> |
15 | 15 |
16 #include <libxml/xmlmemory.h> | 16 #include <libxml/xmlmemory.h> |
17 #include <libxml/uri.h> | 17 #include <libxml/uri.h> |
18 #include <libxml/globals.h> | 18 #include <libxml/globals.h> |
19 #include <libxml/xmlerror.h> | 19 #include <libxml/xmlerror.h> |
20 | 20 |
| 21 /** |
| 22 * MAX_URI_LENGTH: |
| 23 * |
| 24 * The definition of the URI regexp in the above RFC has no size limit |
| 25 * In practice they are usually relativey short except for the |
| 26 * data URI scheme as defined in RFC 2397. Even for data URI the usual |
| 27 * maximum size before hitting random practical limits is around 64 KB |
| 28 * and 4KB is usually a maximum admitted limit for proper operations. |
| 29 * The value below is more a security limit than anything else and |
| 30 * really should never be hit by 'normal' operations |
| 31 * Set to 1 MByte in 2012, this is only enforced on output |
| 32 */ |
| 33 #define MAX_URI_LENGTH 1024 * 1024 |
| 34 |
| 35 static void |
| 36 xmlURIErrMemory(const char *extra) |
| 37 { |
| 38 if (extra) |
| 39 __xmlRaiseError(NULL, NULL, NULL, |
| 40 NULL, NULL, XML_FROM_URI, |
| 41 XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, |
| 42 extra, NULL, NULL, 0, 0, |
| 43 "Memory allocation failed : %s\n", extra); |
| 44 else |
| 45 __xmlRaiseError(NULL, NULL, NULL, |
| 46 NULL, NULL, XML_FROM_URI, |
| 47 XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, |
| 48 NULL, NULL, NULL, 0, 0, |
| 49 "Memory allocation failed\n"); |
| 50 } |
| 51 |
21 static void xmlCleanURI(xmlURIPtr uri); | 52 static void xmlCleanURI(xmlURIPtr uri); |
22 | 53 |
23 /* | 54 /* |
24 * Old rule from 2396 used in legacy handling code | 55 * Old rule from 2396 used in legacy handling code |
25 * alpha = lowalpha | upalpha | 56 * alpha = lowalpha | upalpha |
26 */ | 57 */ |
27 #define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x)) | 58 #define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x)) |
28 | 59 |
29 | 60 |
30 /* | 61 /* |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 ((*(p) >= 'A') && (*(p) <= 'F'))) | 151 ((*(p) >= 'A') && (*(p) <= 'F'))) |
121 | 152 |
122 /* | 153 /* |
123 * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" | 154 * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" |
124 * / "*" / "+" / "," / ";" / "=" | 155 * / "*" / "+" / "," / ";" / "=" |
125 */ | 156 */ |
126 #define ISA_SUB_DELIM(p) \ | 157 #define ISA_SUB_DELIM(p) \ |
127 (((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) || \ | 158 (((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) || \ |
128 ((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) || \ | 159 ((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) || \ |
129 ((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) || \ | 160 ((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) || \ |
130 ((*(p) == '='))) | 161 ((*(p) == '=')) || ((*(p) == '\''))) |
131 | 162 |
132 /* | 163 /* |
133 * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" | 164 * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" |
134 */ | 165 */ |
135 #define ISA_GEN_DELIM(p) \ | 166 #define ISA_GEN_DELIM(p) \ |
136 (((*(p) == ':')) || ((*(p) == '/')) || ((*(p) == '?')) || \ | 167 (((*(p) == ':')) || ((*(p) == '/')) || ((*(p) == '?')) || \ |
137 ((*(p) == '#')) || ((*(p) == '[')) || ((*(p) == ']')) || \ | 168 ((*(p) == '#')) || ((*(p) == '[')) || ((*(p) == ']')) || \ |
138 ((*(p) == '@'))) | 169 ((*(p) == '@'))) |
139 | 170 |
140 /* | 171 /* |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 { | 752 { |
722 const char *cur; | 753 const char *cur; |
723 int ret; | 754 int ret; |
724 | 755 |
725 cur = *str; | 756 cur = *str; |
726 | 757 |
727 if ((*cur == '/') && (*(cur + 1) == '/')) { | 758 if ((*cur == '/') && (*(cur + 1) == '/')) { |
728 cur += 2; | 759 cur += 2; |
729 ret = xmlParse3986Authority(uri, &cur); | 760 ret = xmlParse3986Authority(uri, &cur); |
730 if (ret != 0) return(ret); | 761 if (ret != 0) return(ret); |
| 762 if (uri->server == NULL) |
| 763 uri->port = -1; |
731 ret = xmlParse3986PathAbEmpty(uri, &cur); | 764 ret = xmlParse3986PathAbEmpty(uri, &cur); |
732 if (ret != 0) return(ret); | 765 if (ret != 0) return(ret); |
733 *str = cur; | 766 *str = cur; |
734 return(0); | 767 return(0); |
735 } else if (*cur == '/') { | 768 } else if (*cur == '/') { |
736 ret = xmlParse3986PathAbsolute(uri, &cur); | 769 ret = xmlParse3986PathAbsolute(uri, &cur); |
737 if (ret != 0) return(ret); | 770 if (ret != 0) return(ret); |
738 } else if (ISA_PCHAR(cur)) { | 771 } else if (ISA_PCHAR(cur)) { |
739 ret = xmlParse3986PathRootless(uri, &cur); | 772 ret = xmlParse3986PathRootless(uri, &cur); |
740 if (ret != 0) return(ret); | 773 if (ret != 0) return(ret); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 * Simply creates an empty xmlURI | 1006 * Simply creates an empty xmlURI |
974 * | 1007 * |
975 * Returns the new structure or NULL in case of error | 1008 * Returns the new structure or NULL in case of error |
976 */ | 1009 */ |
977 xmlURIPtr | 1010 xmlURIPtr |
978 xmlCreateURI(void) { | 1011 xmlCreateURI(void) { |
979 xmlURIPtr ret; | 1012 xmlURIPtr ret; |
980 | 1013 |
981 ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI)); | 1014 ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI)); |
982 if (ret == NULL) { | 1015 if (ret == NULL) { |
983 » xmlGenericError(xmlGenericErrorContext, | 1016 xmlURIErrMemory("creating URI structure\n"); |
984 » » "xmlCreateURI: out of memory\n"); | |
985 return(NULL); | 1017 return(NULL); |
986 } | 1018 } |
987 memset(ret, 0, sizeof(xmlURI)); | 1019 memset(ret, 0, sizeof(xmlURI)); |
988 return(ret); | 1020 return(ret); |
989 } | 1021 } |
990 | 1022 |
991 /** | 1023 /** |
| 1024 * xmlSaveUriRealloc: |
| 1025 * |
| 1026 * Function to handle properly a reallocation when saving an URI |
| 1027 * Also imposes some limit on the length of an URI string output |
| 1028 */ |
| 1029 static xmlChar * |
| 1030 xmlSaveUriRealloc(xmlChar *ret, int *max) { |
| 1031 xmlChar *temp; |
| 1032 int tmp; |
| 1033 |
| 1034 if (*max > MAX_URI_LENGTH) { |
| 1035 xmlURIErrMemory("reaching arbitrary MAX_URI_LENGTH limit\n"); |
| 1036 return(NULL); |
| 1037 } |
| 1038 tmp = *max * 2; |
| 1039 temp = (xmlChar *) xmlRealloc(ret, (tmp + 1)); |
| 1040 if (temp == NULL) { |
| 1041 xmlURIErrMemory("saving URI\n"); |
| 1042 return(NULL); |
| 1043 } |
| 1044 *max = tmp; |
| 1045 return(temp); |
| 1046 } |
| 1047 |
| 1048 /** |
992 * xmlSaveUri: | 1049 * xmlSaveUri: |
993 * @uri: pointer to an xmlURI | 1050 * @uri: pointer to an xmlURI |
994 * | 1051 * |
995 * Save the URI as an escaped string | 1052 * Save the URI as an escaped string |
996 * | 1053 * |
997 * Returns a new string (to be deallocated by caller) | 1054 * Returns a new string (to be deallocated by caller) |
998 */ | 1055 */ |
999 xmlChar * | 1056 xmlChar * |
1000 xmlSaveUri(xmlURIPtr uri) { | 1057 xmlSaveUri(xmlURIPtr uri) { |
1001 xmlChar *ret = NULL; | 1058 xmlChar *ret = NULL; |
1002 xmlChar *temp; | 1059 xmlChar *temp; |
1003 const char *p; | 1060 const char *p; |
1004 int len; | 1061 int len; |
1005 int max; | 1062 int max; |
1006 | 1063 |
1007 if (uri == NULL) return(NULL); | 1064 if (uri == NULL) return(NULL); |
1008 | 1065 |
1009 | 1066 |
1010 max = 80; | 1067 max = 80; |
1011 ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar)); | 1068 ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar)); |
1012 if (ret == NULL) { | 1069 if (ret == NULL) { |
1013 » xmlGenericError(xmlGenericErrorContext, | 1070 xmlURIErrMemory("saving URI\n"); |
1014 » » "xmlSaveUri: out of memory\n"); | |
1015 return(NULL); | 1071 return(NULL); |
1016 } | 1072 } |
1017 len = 0; | 1073 len = 0; |
1018 | 1074 |
1019 if (uri->scheme != NULL) { | 1075 if (uri->scheme != NULL) { |
1020 p = uri->scheme; | 1076 p = uri->scheme; |
1021 while (*p != 0) { | 1077 while (*p != 0) { |
1022 if (len >= max) { | 1078 if (len >= max) { |
1023 » » max *= 2; | 1079 temp = xmlSaveUriRealloc(ret, &max); |
1024 » » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); | 1080 if (temp == NULL) goto mem_error; |
1025 » » if (temp == NULL) { | |
1026 » » xmlGenericError(xmlGenericErrorContext, | |
1027 » » » "xmlSaveUri: out of memory\n"); | |
1028 » » xmlFree(ret); | |
1029 » » return(NULL); | |
1030 » » } | |
1031 ret = temp; | 1081 ret = temp; |
1032 } | 1082 } |
1033 ret[len++] = *p++; | 1083 ret[len++] = *p++; |
1034 } | 1084 } |
1035 if (len >= max) { | 1085 if (len >= max) { |
1036 » max *= 2; | 1086 temp = xmlSaveUriRealloc(ret, &max); |
1037 » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); | 1087 if (temp == NULL) goto mem_error; |
1038 » if (temp == NULL) { | 1088 ret = temp; |
1039 » » xmlGenericError(xmlGenericErrorContext, | |
1040 » » » "xmlSaveUri: out of memory\n"); | |
1041 » » xmlFree(ret); | |
1042 » » return(NULL); | |
1043 » } | |
1044 » ret = temp; | |
1045 } | 1089 } |
1046 ret[len++] = ':'; | 1090 ret[len++] = ':'; |
1047 } | 1091 } |
1048 if (uri->opaque != NULL) { | 1092 if (uri->opaque != NULL) { |
1049 p = uri->opaque; | 1093 p = uri->opaque; |
1050 while (*p != 0) { | 1094 while (*p != 0) { |
1051 if (len + 3 >= max) { | 1095 if (len + 3 >= max) { |
1052 » » max *= 2; | 1096 temp = xmlSaveUriRealloc(ret, &max); |
1053 » » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); | 1097 if (temp == NULL) goto mem_error; |
1054 » » if (temp == NULL) { | 1098 ret = temp; |
1055 » » xmlGenericError(xmlGenericErrorContext, | |
1056 » » » "xmlSaveUri: out of memory\n"); | |
1057 » » xmlFree(ret); | |
1058 » » return(NULL); | |
1059 » » } | |
1060 » » ret = temp; | |
1061 } | 1099 } |
1062 if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p))) | 1100 if (IS_RESERVED(*(p)) || IS_UNRESERVED(*(p))) |
1063 ret[len++] = *p++; | 1101 ret[len++] = *p++; |
1064 else { | 1102 else { |
1065 int val = *(unsigned char *)p++; | 1103 int val = *(unsigned char *)p++; |
1066 int hi = val / 0x10, lo = val % 0x10; | 1104 int hi = val / 0x10, lo = val % 0x10; |
1067 ret[len++] = '%'; | 1105 ret[len++] = '%'; |
1068 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); | 1106 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); |
1069 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); | 1107 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); |
1070 } | 1108 } |
1071 } | 1109 } |
1072 } else { | 1110 } else { |
1073 » if (uri->server != NULL) { | 1111 » if ((uri->server != NULL) || (uri->port == -1)) { |
1074 if (len + 3 >= max) { | 1112 if (len + 3 >= max) { |
1075 » » max *= 2; | 1113 temp = xmlSaveUriRealloc(ret, &max); |
1076 » » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); | 1114 if (temp == NULL) goto mem_error; |
1077 » » if (temp == NULL) { | 1115 ret = temp; |
1078 » » xmlGenericError(xmlGenericErrorContext, | |
1079 » » » "xmlSaveUri: out of memory\n"); | |
1080 xmlFree(ret); | |
1081 » » return(NULL); | |
1082 » » } | |
1083 » » ret = temp; | |
1084 } | 1116 } |
1085 ret[len++] = '/'; | 1117 ret[len++] = '/'; |
1086 ret[len++] = '/'; | 1118 ret[len++] = '/'; |
1087 if (uri->user != NULL) { | 1119 if (uri->user != NULL) { |
1088 p = uri->user; | 1120 p = uri->user; |
1089 while (*p != 0) { | 1121 while (*p != 0) { |
1090 if (len + 3 >= max) { | 1122 if (len + 3 >= max) { |
1091 » » » max *= 2; | 1123 temp = xmlSaveUriRealloc(ret, &max); |
1092 » » » temp = (xmlChar *) xmlRealloc(ret, | 1124 if (temp == NULL) goto mem_error; |
1093 » » » » (max + 1) * sizeof(xmlChar)); | 1125 ret = temp; |
1094 » » » if (temp == NULL) { | |
1095 » » » xmlGenericError(xmlGenericErrorContext, | |
1096 » » » » "xmlSaveUri: out of memory\n"); | |
1097 » » » xmlFree(ret); | |
1098 » » » return(NULL); | |
1099 » » » } | |
1100 » » » ret = temp; | |
1101 } | 1126 } |
1102 if ((IS_UNRESERVED(*(p))) || | 1127 if ((IS_UNRESERVED(*(p))) || |
1103 ((*(p) == ';')) || ((*(p) == ':')) || | 1128 ((*(p) == ';')) || ((*(p) == ':')) || |
1104 ((*(p) == '&')) || ((*(p) == '=')) || | 1129 ((*(p) == '&')) || ((*(p) == '=')) || |
1105 ((*(p) == '+')) || ((*(p) == '$')) || | 1130 ((*(p) == '+')) || ((*(p) == '$')) || |
1106 ((*(p) == ','))) | 1131 ((*(p) == ','))) |
1107 ret[len++] = *p++; | 1132 ret[len++] = *p++; |
1108 else { | 1133 else { |
1109 int val = *(unsigned char *)p++; | 1134 int val = *(unsigned char *)p++; |
1110 int hi = val / 0x10, lo = val % 0x10; | 1135 int hi = val / 0x10, lo = val % 0x10; |
1111 ret[len++] = '%'; | 1136 ret[len++] = '%'; |
1112 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); | 1137 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); |
1113 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); | 1138 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); |
1114 } | 1139 } |
1115 } | 1140 } |
1116 if (len + 3 >= max) { | 1141 if (len + 3 >= max) { |
1117 » » max *= 2; | 1142 temp = xmlSaveUriRealloc(ret, &max); |
1118 » » temp = (xmlChar *) xmlRealloc(ret, | 1143 if (temp == NULL) goto mem_error; |
1119 » » » (max + 1) * sizeof(xmlChar)); | 1144 ret = temp; |
1120 » » if (temp == NULL) { | |
1121 » » » xmlGenericError(xmlGenericErrorContext, | |
1122 » » » » "xmlSaveUri: out of memory\n"); | |
1123 » » » xmlFree(ret); | |
1124 » » » return(NULL); | |
1125 » » } | |
1126 » » ret = temp; | |
1127 } | 1145 } |
1128 ret[len++] = '@'; | 1146 ret[len++] = '@'; |
1129 } | 1147 } |
1130 » p = uri->server; | 1148 » if (uri->server != NULL) { |
1131 » while (*p != 0) { | 1149 » » p = uri->server; |
1132 » » if (len >= max) { | 1150 » » while (*p != 0) { |
1133 » » max *= 2; | 1151 » » if (len >= max) { |
1134 » » temp = (xmlChar *) xmlRealloc(ret, | 1152 » » » temp = xmlSaveUriRealloc(ret, &max); |
1135 » » » (max + 1) * sizeof(xmlChar)); | 1153 » » » if (temp == NULL) goto mem_error; |
1136 » » if (temp == NULL) { | 1154 » » » ret = temp; |
1137 » » » xmlGenericError(xmlGenericErrorContext, | |
1138 » » » » "xmlSaveUri: out of memory\n"); | |
1139 » » » xmlFree(ret); | |
1140 » » » return(NULL); | |
1141 } | 1155 } |
1142 » » ret = temp; | 1156 » » ret[len++] = *p++; |
1143 } | 1157 } |
1144 » » ret[len++] = *p++; | 1158 » » if (uri->port > 0) { |
1145 » } | 1159 » » if (len + 10 >= max) { |
1146 » if (uri->port > 0) { | 1160 » » » temp = xmlSaveUriRealloc(ret, &max); |
1147 » » if (len + 10 >= max) { | 1161 » » » if (temp == NULL) goto mem_error; |
1148 » » max *= 2; | 1162 » » » ret = temp; |
1149 » » temp = (xmlChar *) xmlRealloc(ret, | |
1150 » » » (max + 1) * sizeof(xmlChar)); | |
1151 » » if (temp == NULL) { | |
1152 » » » xmlGenericError(xmlGenericErrorContext, | |
1153 » » » » "xmlSaveUri: out of memory\n"); | |
1154 xmlFree(ret); | |
1155 » » » return(NULL); | |
1156 } | 1163 } |
1157 » » ret = temp; | 1164 » » len += snprintf((char *) &ret[len], max - len, ":%d", uri->p
ort); |
1158 } | 1165 } |
1159 len += snprintf((char *) &ret[len], max - len, ":%d", uri->port)
; | |
1160 } | 1166 } |
1161 } else if (uri->authority != NULL) { | 1167 } else if (uri->authority != NULL) { |
1162 if (len + 3 >= max) { | 1168 if (len + 3 >= max) { |
1163 » » max *= 2; | 1169 temp = xmlSaveUriRealloc(ret, &max); |
1164 » » temp = (xmlChar *) xmlRealloc(ret, | 1170 if (temp == NULL) goto mem_error; |
1165 » » » (max + 1) * sizeof(xmlChar)); | 1171 ret = temp; |
1166 » » if (temp == NULL) { | |
1167 » » » xmlGenericError(xmlGenericErrorContext, | |
1168 » » » » "xmlSaveUri: out of memory\n"); | |
1169 xmlFree(ret); | |
1170 » » » return(NULL); | |
1171 » » } | |
1172 » » ret = temp; | |
1173 } | 1172 } |
1174 ret[len++] = '/'; | 1173 ret[len++] = '/'; |
1175 ret[len++] = '/'; | 1174 ret[len++] = '/'; |
1176 p = uri->authority; | 1175 p = uri->authority; |
1177 while (*p != 0) { | 1176 while (*p != 0) { |
1178 if (len + 3 >= max) { | 1177 if (len + 3 >= max) { |
1179 » » max *= 2; | 1178 temp = xmlSaveUriRealloc(ret, &max); |
1180 » » temp = (xmlChar *) xmlRealloc(ret, | 1179 if (temp == NULL) goto mem_error; |
1181 » » » (max + 1) * sizeof(xmlChar)); | 1180 ret = temp; |
1182 » » if (temp == NULL) { | |
1183 » » » xmlGenericError(xmlGenericErrorContext, | |
1184 » » » » "xmlSaveUri: out of memory\n"); | |
1185 xmlFree(ret); | |
1186 » » » return(NULL); | |
1187 » » } | |
1188 » » ret = temp; | |
1189 } | 1181 } |
1190 if ((IS_UNRESERVED(*(p))) || | 1182 if ((IS_UNRESERVED(*(p))) || |
1191 ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || | 1183 ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || |
1192 ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || | 1184 ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || |
1193 ((*(p) == '=')) || ((*(p) == '+'))) | 1185 ((*(p) == '=')) || ((*(p) == '+'))) |
1194 ret[len++] = *p++; | 1186 ret[len++] = *p++; |
1195 else { | 1187 else { |
1196 int val = *(unsigned char *)p++; | 1188 int val = *(unsigned char *)p++; |
1197 int hi = val / 0x10, lo = val % 0x10; | 1189 int hi = val / 0x10, lo = val % 0x10; |
1198 ret[len++] = '%'; | 1190 ret[len++] = '%'; |
1199 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); | 1191 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); |
1200 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); | 1192 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); |
1201 } | 1193 } |
1202 } | 1194 } |
1203 } else if (uri->scheme != NULL) { | 1195 } else if (uri->scheme != NULL) { |
1204 if (len + 3 >= max) { | 1196 if (len + 3 >= max) { |
1205 » » max *= 2; | 1197 temp = xmlSaveUriRealloc(ret, &max); |
1206 » » temp = (xmlChar *) xmlRealloc(ret, | 1198 if (temp == NULL) goto mem_error; |
1207 » » » (max + 1) * sizeof(xmlChar)); | 1199 ret = temp; |
1208 » » if (temp == NULL) { | |
1209 » » » xmlGenericError(xmlGenericErrorContext, | |
1210 » » » » "xmlSaveUri: out of memory\n"); | |
1211 xmlFree(ret); | |
1212 » » » return(NULL); | |
1213 » » } | |
1214 » » ret = temp; | |
1215 } | 1200 } |
1216 ret[len++] = '/'; | |
1217 ret[len++] = '/'; | |
1218 } | 1201 } |
1219 if (uri->path != NULL) { | 1202 if (uri->path != NULL) { |
1220 p = uri->path; | 1203 p = uri->path; |
1221 /* | 1204 /* |
1222 * the colon in file:///d: should not be escaped or | 1205 * the colon in file:///d: should not be escaped or |
1223 * Windows accesses fail later. | 1206 * Windows accesses fail later. |
1224 */ | 1207 */ |
1225 if ((uri->scheme != NULL) && | 1208 if ((uri->scheme != NULL) && |
1226 (p[0] == '/') && | 1209 (p[0] == '/') && |
1227 (((p[1] >= 'a') && (p[1] <= 'z')) || | 1210 (((p[1] >= 'a') && (p[1] <= 'z')) || |
1228 ((p[1] >= 'A') && (p[1] <= 'Z'))) && | 1211 ((p[1] >= 'A') && (p[1] <= 'Z'))) && |
1229 (p[2] == ':') && | 1212 (p[2] == ':') && |
1230 (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) { | 1213 (xmlStrEqual(BAD_CAST uri->scheme, BAD_CAST "file"))) { |
1231 if (len + 3 >= max) { | 1214 if (len + 3 >= max) { |
1232 » » max *= 2; | 1215 temp = xmlSaveUriRealloc(ret, &max); |
1233 » » ret = (xmlChar *) xmlRealloc(ret, | 1216 if (temp == NULL) goto mem_error; |
1234 » » » (max + 1) * sizeof(xmlChar)); | 1217 ret = temp; |
1235 » » if (ret == NULL) { | |
1236 » » » xmlGenericError(xmlGenericErrorContext, | |
1237 » » » » "xmlSaveUri: out of memory\n"); | |
1238 » » » return(NULL); | |
1239 » » } | |
1240 } | 1218 } |
1241 ret[len++] = *p++; | 1219 ret[len++] = *p++; |
1242 ret[len++] = *p++; | 1220 ret[len++] = *p++; |
1243 ret[len++] = *p++; | 1221 ret[len++] = *p++; |
1244 } | 1222 } |
1245 while (*p != 0) { | 1223 while (*p != 0) { |
1246 if (len + 3 >= max) { | 1224 if (len + 3 >= max) { |
1247 » » max *= 2; | 1225 temp = xmlSaveUriRealloc(ret, &max); |
1248 » » temp = (xmlChar *) xmlRealloc(ret, | 1226 if (temp == NULL) goto mem_error; |
1249 » » » (max + 1) * sizeof(xmlChar)); | 1227 ret = temp; |
1250 » » if (temp == NULL) { | |
1251 » » » xmlGenericError(xmlGenericErrorContext, | |
1252 » » » » "xmlSaveUri: out of memory\n"); | |
1253 xmlFree(ret); | |
1254 » » » return(NULL); | |
1255 » » } | |
1256 » » ret = temp; | |
1257 } | 1228 } |
1258 if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) || | 1229 if ((IS_UNRESERVED(*(p))) || ((*(p) == '/')) || |
1259 ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || | 1230 ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || |
1260 ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || | 1231 ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || |
1261 ((*(p) == ','))) | 1232 ((*(p) == ','))) |
1262 ret[len++] = *p++; | 1233 ret[len++] = *p++; |
1263 else { | 1234 else { |
1264 int val = *(unsigned char *)p++; | 1235 int val = *(unsigned char *)p++; |
1265 int hi = val / 0x10, lo = val % 0x10; | 1236 int hi = val / 0x10, lo = val % 0x10; |
1266 ret[len++] = '%'; | 1237 ret[len++] = '%'; |
1267 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); | 1238 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); |
1268 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); | 1239 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); |
1269 } | 1240 } |
1270 } | 1241 } |
1271 } | 1242 } |
1272 if (uri->query_raw != NULL) { | 1243 if (uri->query_raw != NULL) { |
1273 if (len + 1 >= max) { | 1244 if (len + 1 >= max) { |
1274 » » max *= 2; | 1245 temp = xmlSaveUriRealloc(ret, &max); |
1275 » » temp = (xmlChar *) xmlRealloc(ret, | 1246 if (temp == NULL) goto mem_error; |
1276 » » » (max + 1) * sizeof(xmlChar)); | 1247 ret = temp; |
1277 » » if (temp == NULL) { | |
1278 » » » xmlGenericError(xmlGenericErrorContext, | |
1279 » » » » "xmlSaveUri: out of memory\n"); | |
1280 xmlFree(ret); | |
1281 » » » return(NULL); | |
1282 » » } | |
1283 » » ret = temp; | |
1284 } | 1248 } |
1285 ret[len++] = '?'; | 1249 ret[len++] = '?'; |
1286 p = uri->query_raw; | 1250 p = uri->query_raw; |
1287 while (*p != 0) { | 1251 while (*p != 0) { |
1288 if (len + 1 >= max) { | 1252 if (len + 1 >= max) { |
1289 » » max *= 2; | 1253 temp = xmlSaveUriRealloc(ret, &max); |
1290 » » temp = (xmlChar *) xmlRealloc(ret, | 1254 if (temp == NULL) goto mem_error; |
1291 » » » (max + 1) * sizeof(xmlChar)); | 1255 ret = temp; |
1292 » » if (temp == NULL) { | |
1293 » » » xmlGenericError(xmlGenericErrorContext, | |
1294 » » » » "xmlSaveUri: out of memory\n"); | |
1295 xmlFree(ret); | |
1296 » » » return(NULL); | |
1297 » » } | |
1298 » » ret = temp; | |
1299 } | 1256 } |
1300 ret[len++] = *p++; | 1257 ret[len++] = *p++; |
1301 } | 1258 } |
1302 } else if (uri->query != NULL) { | 1259 } else if (uri->query != NULL) { |
1303 if (len + 3 >= max) { | 1260 if (len + 3 >= max) { |
1304 » » max *= 2; | 1261 temp = xmlSaveUriRealloc(ret, &max); |
1305 » » temp = (xmlChar *) xmlRealloc(ret, | 1262 if (temp == NULL) goto mem_error; |
1306 » » » (max + 1) * sizeof(xmlChar)); | 1263 ret = temp; |
1307 » » if (temp == NULL) { | |
1308 » » » xmlGenericError(xmlGenericErrorContext, | |
1309 » » » » "xmlSaveUri: out of memory\n"); | |
1310 xmlFree(ret); | |
1311 » » » return(NULL); | |
1312 » » } | |
1313 » » ret = temp; | |
1314 } | 1264 } |
1315 ret[len++] = '?'; | 1265 ret[len++] = '?'; |
1316 p = uri->query; | 1266 p = uri->query; |
1317 while (*p != 0) { | 1267 while (*p != 0) { |
1318 if (len + 3 >= max) { | 1268 if (len + 3 >= max) { |
1319 » » max *= 2; | 1269 temp = xmlSaveUriRealloc(ret, &max); |
1320 » » temp = (xmlChar *) xmlRealloc(ret, | 1270 if (temp == NULL) goto mem_error; |
1321 » » » (max + 1) * sizeof(xmlChar)); | 1271 ret = temp; |
1322 » » if (temp == NULL) { | |
1323 » » » xmlGenericError(xmlGenericErrorContext, | |
1324 » » » » "xmlSaveUri: out of memory\n"); | |
1325 xmlFree(ret); | |
1326 » » » return(NULL); | |
1327 » » } | |
1328 » » ret = temp; | |
1329 } | 1272 } |
1330 » » if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) | 1273 » » if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) |
1331 ret[len++] = *p++; | 1274 ret[len++] = *p++; |
1332 else { | 1275 else { |
1333 int val = *(unsigned char *)p++; | 1276 int val = *(unsigned char *)p++; |
1334 int hi = val / 0x10, lo = val % 0x10; | 1277 int hi = val / 0x10, lo = val % 0x10; |
1335 ret[len++] = '%'; | 1278 ret[len++] = '%'; |
1336 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); | 1279 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); |
1337 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); | 1280 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); |
1338 } | 1281 } |
1339 } | 1282 } |
1340 } | 1283 } |
1341 } | 1284 } |
1342 if (uri->fragment != NULL) { | 1285 if (uri->fragment != NULL) { |
1343 if (len + 3 >= max) { | 1286 if (len + 3 >= max) { |
1344 » max *= 2; | 1287 temp = xmlSaveUriRealloc(ret, &max); |
1345 » temp = (xmlChar *) xmlRealloc(ret, | 1288 if (temp == NULL) goto mem_error; |
1346 » » (max + 1) * sizeof(xmlChar)); | 1289 ret = temp; |
1347 » if (temp == NULL) { | |
1348 » » » xmlGenericError(xmlGenericErrorContext, | |
1349 » » » » "xmlSaveUri: out of memory\n"); | |
1350 xmlFree(ret); | |
1351 » » » return(NULL); | |
1352 » » } | |
1353 » » ret = temp; | |
1354 } | 1290 } |
1355 ret[len++] = '#'; | 1291 ret[len++] = '#'; |
1356 p = uri->fragment; | 1292 p = uri->fragment; |
1357 while (*p != 0) { | 1293 while (*p != 0) { |
1358 if (len + 3 >= max) { | 1294 if (len + 3 >= max) { |
1359 » » max *= 2; | 1295 temp = xmlSaveUriRealloc(ret, &max); |
1360 » » temp = (xmlChar *) xmlRealloc(ret, | 1296 if (temp == NULL) goto mem_error; |
1361 » » » (max + 1) * sizeof(xmlChar)); | 1297 ret = temp; |
1362 » » if (temp == NULL) { | |
1363 » » » xmlGenericError(xmlGenericErrorContext, | |
1364 » » » » "xmlSaveUri: out of memory\n"); | |
1365 xmlFree(ret); | |
1366 » » » return(NULL); | |
1367 » » } | |
1368 » » ret = temp; | |
1369 } | 1298 } |
1370 » if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) | 1299 » if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) |
1371 ret[len++] = *p++; | 1300 ret[len++] = *p++; |
1372 else { | 1301 else { |
1373 int val = *(unsigned char *)p++; | 1302 int val = *(unsigned char *)p++; |
1374 int hi = val / 0x10, lo = val % 0x10; | 1303 int hi = val / 0x10, lo = val % 0x10; |
1375 ret[len++] = '%'; | 1304 ret[len++] = '%'; |
1376 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); | 1305 ret[len++] = hi + (hi > 9? 'A'-10 : '0'); |
1377 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); | 1306 ret[len++] = lo + (lo > 9? 'A'-10 : '0'); |
1378 } | 1307 } |
1379 } | 1308 } |
1380 } | 1309 } |
1381 if (len >= max) { | 1310 if (len >= max) { |
1382 » max *= 2; | 1311 temp = xmlSaveUriRealloc(ret, &max); |
1383 » temp = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); | 1312 if (temp == NULL) goto mem_error; |
1384 » if (temp == NULL) { | 1313 ret = temp; |
1385 » » » xmlGenericError(xmlGenericErrorContext, | |
1386 » » » » "xmlSaveUri: out of memory\n"); | |
1387 xmlFree(ret); | |
1388 » » » return(NULL); | |
1389 » » } | |
1390 » » ret = temp; | |
1391 } | 1314 } |
1392 ret[len] = 0; | 1315 ret[len] = 0; |
1393 return(ret); | 1316 return(ret); |
| 1317 |
| 1318 mem_error: |
| 1319 xmlFree(ret); |
| 1320 return(NULL); |
1394 } | 1321 } |
1395 | 1322 |
1396 /** | 1323 /** |
1397 * xmlPrintURI: | 1324 * xmlPrintURI: |
1398 * @stream: a FILE* for the output | 1325 * @stream: a FILE* for the output |
1399 * @uri: pointer to an xmlURI | 1326 * @uri: pointer to an xmlURI |
1400 * | 1327 * |
1401 * Prints the URI in the stream @stream. | 1328 * Prints the URI in the stream @stream. |
1402 */ | 1329 */ |
1403 void | 1330 void |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1597 * while maintaining two pointers into the buffer, so just compact | 1524 * while maintaining two pointers into the buffer, so just compact |
1598 * the whole buffer now. | 1525 * the whole buffer now. |
1599 */ | 1526 */ |
1600 | 1527 |
1601 /* If this is the end of the buffer, we're done. */ | 1528 /* If this is the end of the buffer, we're done. */ |
1602 if (segp[2] == '\0') { | 1529 if (segp[2] == '\0') { |
1603 cur[0] = '\0'; | 1530 cur[0] = '\0'; |
1604 break; | 1531 break; |
1605 } | 1532 } |
1606 /* Valgrind complained, strcpy(cur, segp + 3); */ | 1533 /* Valgrind complained, strcpy(cur, segp + 3); */ |
1607 » /* string will overlap, do not use strcpy */ | 1534 /* string will overlap, do not use strcpy */ |
1608 » tmp = cur; | 1535 tmp = cur; |
1609 » segp += 3; | 1536 segp += 3; |
1610 » while ((*tmp++ = *segp++) != 0); | 1537 while ((*tmp++ = *segp++) != 0) |
| 1538 ; |
1611 | 1539 |
1612 /* If there are no previous segments, then keep going from here. */ | 1540 /* If there are no previous segments, then keep going from here. */ |
1613 segp = cur; | 1541 segp = cur; |
1614 while ((segp > path) && ((--segp)[0] == '/')) | 1542 while ((segp > path) && ((--segp)[0] == '/')) |
1615 ; | 1543 ; |
1616 if (segp == path) | 1544 if (segp == path) |
1617 continue; | 1545 continue; |
1618 | 1546 |
1619 /* "segp" is pointing to the end of a previous segment; find it's | 1547 /* "segp" is pointing to the end of a previous segment; find it's |
1620 * start. We need to back up to the previous segment and start | 1548 * start. We need to back up to the previous segment and start |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 const char *in; | 1613 const char *in; |
1686 | 1614 |
1687 if (str == NULL) | 1615 if (str == NULL) |
1688 return(NULL); | 1616 return(NULL); |
1689 if (len <= 0) len = strlen(str); | 1617 if (len <= 0) len = strlen(str); |
1690 if (len < 0) return(NULL); | 1618 if (len < 0) return(NULL); |
1691 | 1619 |
1692 if (target == NULL) { | 1620 if (target == NULL) { |
1693 ret = (char *) xmlMallocAtomic(len + 1); | 1621 ret = (char *) xmlMallocAtomic(len + 1); |
1694 if (ret == NULL) { | 1622 if (ret == NULL) { |
1695 » xmlGenericError(xmlGenericErrorContext, | 1623 xmlURIErrMemory("unescaping URI value\n"); |
1696 » » "xmlURIUnescapeString: out of memory\n"); | |
1697 return(NULL); | 1624 return(NULL); |
1698 } | 1625 } |
1699 } else | 1626 } else |
1700 ret = target; | 1627 ret = target; |
1701 in = str; | 1628 in = str; |
1702 out = ret; | 1629 out = ret; |
1703 while(len > 0) { | 1630 while(len > 0) { |
1704 if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) { | 1631 if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) { |
1705 in++; | 1632 in++; |
1706 » if ((*in >= '0') && (*in <= '9')) | 1633 » if ((*in >= '0') && (*in <= '9')) |
1707 *out = (*in - '0'); | 1634 *out = (*in - '0'); |
1708 else if ((*in >= 'a') && (*in <= 'f')) | 1635 else if ((*in >= 'a') && (*in <= 'f')) |
1709 *out = (*in - 'a') + 10; | 1636 *out = (*in - 'a') + 10; |
1710 else if ((*in >= 'A') && (*in <= 'F')) | 1637 else if ((*in >= 'A') && (*in <= 'F')) |
1711 *out = (*in - 'A') + 10; | 1638 *out = (*in - 'A') + 10; |
1712 in++; | 1639 in++; |
1713 » if ((*in >= '0') && (*in <= '9')) | 1640 » if ((*in >= '0') && (*in <= '9')) |
1714 *out = *out * 16 + (*in - '0'); | 1641 *out = *out * 16 + (*in - '0'); |
1715 else if ((*in >= 'a') && (*in <= 'f')) | 1642 else if ((*in >= 'a') && (*in <= 'f')) |
1716 *out = *out * 16 + (*in - 'a') + 10; | 1643 *out = *out * 16 + (*in - 'a') + 10; |
1717 else if ((*in >= 'A') && (*in <= 'F')) | 1644 else if ((*in >= 'A') && (*in <= 'F')) |
1718 *out = *out * 16 + (*in - 'A') + 10; | 1645 *out = *out * 16 + (*in - 'A') + 10; |
1719 in++; | 1646 in++; |
1720 len -= 3; | 1647 len -= 3; |
1721 out++; | 1648 out++; |
1722 } else { | 1649 } else { |
1723 *out++ = *in++; | 1650 *out++ = *in++; |
(...skipping 12 matching lines...) Expand all Loading... |
1736 * This routine escapes a string to hex, ignoring reserved characters (a-z) | 1663 * This routine escapes a string to hex, ignoring reserved characters (a-z) |
1737 * and the characters in the exception list. | 1664 * and the characters in the exception list. |
1738 * | 1665 * |
1739 * Returns a new escaped string or NULL in case of error. | 1666 * Returns a new escaped string or NULL in case of error. |
1740 */ | 1667 */ |
1741 xmlChar * | 1668 xmlChar * |
1742 xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) { | 1669 xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) { |
1743 xmlChar *ret, ch; | 1670 xmlChar *ret, ch; |
1744 xmlChar *temp; | 1671 xmlChar *temp; |
1745 const xmlChar *in; | 1672 const xmlChar *in; |
1746 | 1673 int len, out; |
1747 unsigned int len, out; | |
1748 | 1674 |
1749 if (str == NULL) | 1675 if (str == NULL) |
1750 return(NULL); | 1676 return(NULL); |
1751 if (str[0] == 0) | 1677 if (str[0] == 0) |
1752 return(xmlStrdup(str)); | 1678 return(xmlStrdup(str)); |
1753 len = xmlStrlen(str); | 1679 len = xmlStrlen(str); |
1754 if (!(len > 0)) return(NULL); | 1680 if (!(len > 0)) return(NULL); |
1755 | 1681 |
1756 len += 20; | 1682 len += 20; |
1757 ret = (xmlChar *) xmlMallocAtomic(len); | 1683 ret = (xmlChar *) xmlMallocAtomic(len); |
1758 if (ret == NULL) { | 1684 if (ret == NULL) { |
1759 » xmlGenericError(xmlGenericErrorContext, | 1685 xmlURIErrMemory("escaping URI value\n"); |
1760 » » "xmlURIEscapeStr: out of memory\n"); | |
1761 return(NULL); | 1686 return(NULL); |
1762 } | 1687 } |
1763 in = (const xmlChar *) str; | 1688 in = (const xmlChar *) str; |
1764 out = 0; | 1689 out = 0; |
1765 while(*in != 0) { | 1690 while(*in != 0) { |
1766 if (len - out <= 3) { | 1691 if (len - out <= 3) { |
1767 » len += 20; | 1692 temp = xmlSaveUriRealloc(ret, &len); |
1768 » temp = (xmlChar *) xmlRealloc(ret, len); | |
1769 if (temp == NULL) { | 1693 if (temp == NULL) { |
1770 » » xmlGenericError(xmlGenericErrorContext, | 1694 xmlURIErrMemory("escaping URI value\n"); |
1771 » » » "xmlURIEscapeStr: out of memory\n"); | |
1772 xmlFree(ret); | 1695 xmlFree(ret); |
1773 return(NULL); | 1696 return(NULL); |
1774 } | 1697 } |
1775 ret = temp; | 1698 ret = temp; |
1776 } | 1699 } |
1777 | 1700 |
1778 ch = *in; | 1701 ch = *in; |
1779 | 1702 |
1780 if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) { | 1703 if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) { |
1781 unsigned char val; | 1704 unsigned char val; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1816 * - Carl Douglas | 1739 * - Carl Douglas |
1817 */ | 1740 */ |
1818 xmlChar * | 1741 xmlChar * |
1819 xmlURIEscape(const xmlChar * str) | 1742 xmlURIEscape(const xmlChar * str) |
1820 { | 1743 { |
1821 xmlChar *ret, *segment = NULL; | 1744 xmlChar *ret, *segment = NULL; |
1822 xmlURIPtr uri; | 1745 xmlURIPtr uri; |
1823 int ret2; | 1746 int ret2; |
1824 | 1747 |
1825 #define NULLCHK(p) if(!p) { \ | 1748 #define NULLCHK(p) if(!p) { \ |
1826 xmlGenericError(xmlGenericErrorContext, \ | 1749 xmlURIErrMemory("escaping URI value\n"); \ |
1827 "xmlURIEscape: out of memory\n"); \ | 1750 xmlFreeURI(uri); \ |
1828 xmlFreeURI(uri); \ | 1751 return NULL; } \ |
1829 return NULL; } \ | |
1830 | 1752 |
1831 if (str == NULL) | 1753 if (str == NULL) |
1832 return (NULL); | 1754 return (NULL); |
1833 | 1755 |
1834 uri = xmlCreateURI(); | 1756 uri = xmlCreateURI(); |
1835 if (uri != NULL) { | 1757 if (uri != NULL) { |
1836 /* | 1758 /* |
1837 * Allow escaping errors in the unescaped form | 1759 * Allow escaping errors in the unescaped form |
1838 */ | 1760 */ |
1839 uri->cleanup = 1; | 1761 uri->cleanup = 1; |
(...skipping 22 matching lines...) Expand all Loading... |
1862 xmlURIEscapeStr(BAD_CAST uri->authority, BAD_CAST "/?;:@"); | 1784 xmlURIEscapeStr(BAD_CAST uri->authority, BAD_CAST "/?;:@"); |
1863 NULLCHK(segment) | 1785 NULLCHK(segment) |
1864 ret = xmlStrcat(ret, BAD_CAST "//"); | 1786 ret = xmlStrcat(ret, BAD_CAST "//"); |
1865 ret = xmlStrcat(ret, segment); | 1787 ret = xmlStrcat(ret, segment); |
1866 xmlFree(segment); | 1788 xmlFree(segment); |
1867 } | 1789 } |
1868 | 1790 |
1869 if (uri->user) { | 1791 if (uri->user) { |
1870 segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,"); | 1792 segment = xmlURIEscapeStr(BAD_CAST uri->user, BAD_CAST ";:&=+$,"); |
1871 NULLCHK(segment) | 1793 NULLCHK(segment) |
1872 » » ret = xmlStrcat(ret,BAD_CAST "//");» | 1794 » » ret = xmlStrcat(ret,BAD_CAST "//"); |
1873 ret = xmlStrcat(ret, segment); | 1795 ret = xmlStrcat(ret, segment); |
1874 ret = xmlStrcat(ret, BAD_CAST "@"); | 1796 ret = xmlStrcat(ret, BAD_CAST "@"); |
1875 xmlFree(segment); | 1797 xmlFree(segment); |
1876 } | 1798 } |
1877 | 1799 |
1878 if (uri->server) { | 1800 if (uri->server) { |
1879 segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@"); | 1801 segment = xmlURIEscapeStr(BAD_CAST uri->server, BAD_CAST "/?;:@"); |
1880 NULLCHK(segment) | 1802 NULLCHK(segment) |
1881 if (uri->user == NULL) | 1803 if (uri->user == NULL) |
1882 ret = xmlStrcat(ret, BAD_CAST "//"); | 1804 ret = xmlStrcat(ret, BAD_CAST "//"); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1940 * * | 1862 * * |
1941 ************************************************************************/ | 1863 ************************************************************************/ |
1942 | 1864 |
1943 /** | 1865 /** |
1944 * xmlBuildURI: | 1866 * xmlBuildURI: |
1945 * @URI: the URI instance found in the document | 1867 * @URI: the URI instance found in the document |
1946 * @base: the base value | 1868 * @base: the base value |
1947 * | 1869 * |
1948 * Computes he final URI of the reference done by checking that | 1870 * Computes he final URI of the reference done by checking that |
1949 * the given URI is valid, and building the final URI using the | 1871 * the given URI is valid, and building the final URI using the |
1950 * base URI. This is processed according to section 5.2 of the | 1872 * base URI. This is processed according to section 5.2 of the |
1951 * RFC 2396 | 1873 * RFC 2396 |
1952 * | 1874 * |
1953 * 5.2. Resolving Relative References to Absolute Form | 1875 * 5.2. Resolving Relative References to Absolute Form |
1954 * | 1876 * |
1955 * Returns a new URI string (to be freed by the caller) or NULL in case | 1877 * Returns a new URI string (to be freed by the caller) or NULL in case |
1956 * of error. | 1878 * of error. |
1957 */ | 1879 */ |
1958 xmlChar * | 1880 xmlChar * |
1959 xmlBuildURI(const xmlChar *URI, const xmlChar *base) { | 1881 xmlBuildURI(const xmlChar *URI, const xmlChar *base) { |
1960 xmlChar *val = NULL; | 1882 xmlChar *val = NULL; |
1961 int ret, len, indx, cur, out; | 1883 int ret, len, indx, cur, out; |
1962 xmlURIPtr ref = NULL; | 1884 xmlURIPtr ref = NULL; |
1963 xmlURIPtr bas = NULL; | 1885 xmlURIPtr bas = NULL; |
1964 xmlURIPtr res = NULL; | 1886 xmlURIPtr res = NULL; |
1965 | 1887 |
1966 /* | 1888 /* |
1967 * 1) The URI reference is parsed into the potential four components and | 1889 * 1) The URI reference is parsed into the potential four components and |
1968 * fragment identifier, as described in Section 4.3. | 1890 * fragment identifier, as described in Section 4.3. |
1969 * | 1891 * |
1970 * NOTE that a completely empty URI is treated by modern browsers | 1892 * NOTE that a completely empty URI is treated by modern browsers |
1971 * as a reference to "." rather than as a synonym for the current | 1893 * as a reference to "." rather than as a synonym for the current |
1972 * URI. Should we do that here? | 1894 * URI. Should we do that here? |
1973 */ | 1895 */ |
1974 if (URI == NULL) | 1896 if (URI == NULL) |
1975 ret = -1; | 1897 ret = -1; |
1976 else { | 1898 else { |
1977 if (*URI) { | 1899 if (*URI) { |
1978 ref = xmlCreateURI(); | 1900 ref = xmlCreateURI(); |
1979 if (ref == NULL) | 1901 if (ref == NULL) |
1980 goto done; | 1902 goto done; |
1981 ret = xmlParseURIReference(ref, (const char *) URI); | 1903 ret = xmlParseURIReference(ref, (const char *) URI); |
1982 } | 1904 } |
1983 else | 1905 else |
1984 ret = 0; | 1906 ret = 0; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2035 if ((ref->scheme == NULL) && (ref->path == NULL) && | 1957 if ((ref->scheme == NULL) && (ref->path == NULL) && |
2036 ((ref->authority == NULL) && (ref->server == NULL))) { | 1958 ((ref->authority == NULL) && (ref->server == NULL))) { |
2037 if (bas->scheme != NULL) | 1959 if (bas->scheme != NULL) |
2038 res->scheme = xmlMemStrdup(bas->scheme); | 1960 res->scheme = xmlMemStrdup(bas->scheme); |
2039 if (bas->authority != NULL) | 1961 if (bas->authority != NULL) |
2040 res->authority = xmlMemStrdup(bas->authority); | 1962 res->authority = xmlMemStrdup(bas->authority); |
2041 else if (bas->server != NULL) { | 1963 else if (bas->server != NULL) { |
2042 res->server = xmlMemStrdup(bas->server); | 1964 res->server = xmlMemStrdup(bas->server); |
2043 if (bas->user != NULL) | 1965 if (bas->user != NULL) |
2044 res->user = xmlMemStrdup(bas->user); | 1966 res->user = xmlMemStrdup(bas->user); |
2045 » res->port = bas->port;» » | 1967 » res->port = bas->port; |
2046 } | 1968 } |
2047 if (bas->path != NULL) | 1969 if (bas->path != NULL) |
2048 res->path = xmlMemStrdup(bas->path); | 1970 res->path = xmlMemStrdup(bas->path); |
2049 if (ref->query_raw != NULL) | 1971 if (ref->query_raw != NULL) |
2050 res->query_raw = xmlMemStrdup (ref->query_raw); | 1972 res->query_raw = xmlMemStrdup (ref->query_raw); |
2051 else if (ref->query != NULL) | 1973 else if (ref->query != NULL) |
2052 res->query = xmlMemStrdup(ref->query); | 1974 res->query = xmlMemStrdup(ref->query); |
2053 else if (bas->query_raw != NULL) | 1975 else if (bas->query_raw != NULL) |
2054 res->query_raw = xmlMemStrdup(bas->query_raw); | 1976 res->query_raw = xmlMemStrdup(bas->query_raw); |
2055 else if (bas->query != NULL) | 1977 else if (bas->query != NULL) |
2056 res->query = xmlMemStrdup(bas->query); | 1978 res->query = xmlMemStrdup(bas->query); |
2057 if (ref->fragment != NULL) | 1979 if (ref->fragment != NULL) |
2058 res->fragment = xmlMemStrdup(ref->fragment); | 1980 res->fragment = xmlMemStrdup(ref->fragment); |
2059 goto step_7; | 1981 goto step_7; |
2060 } | 1982 } |
2061 | 1983 |
2062 /* | 1984 /* |
2063 * 3) If the scheme component is defined, indicating that the reference | 1985 * 3) If the scheme component is defined, indicating that the reference |
2064 * starts with a scheme name, then the reference is interpreted as an | 1986 * starts with a scheme name, then the reference is interpreted as an |
2065 * absolute URI and we are done. Otherwise, the reference URI's | 1987 * absolute URI and we are done. Otherwise, the reference URI's |
2066 * scheme is inherited from the base URI's scheme component. | 1988 * scheme is inherited from the base URI's scheme component. |
2067 */ | 1989 */ |
2068 if (ref->scheme != NULL) { | 1990 if (ref->scheme != NULL) { |
2069 val = xmlSaveUri(ref); | 1991 val = xmlSaveUri(ref); |
2070 goto done; | 1992 goto done; |
2071 } | 1993 } |
2072 if (bas->scheme != NULL) | 1994 if (bas->scheme != NULL) |
2073 res->scheme = xmlMemStrdup(bas->scheme); | 1995 res->scheme = xmlMemStrdup(bas->scheme); |
2074 | 1996 |
2075 if (ref->query_raw != NULL) | 1997 if (ref->query_raw != NULL) |
2076 res->query_raw = xmlMemStrdup(ref->query_raw); | 1998 res->query_raw = xmlMemStrdup(ref->query_raw); |
2077 else if (ref->query != NULL) | 1999 else if (ref->query != NULL) |
2078 res->query = xmlMemStrdup(ref->query); | 2000 res->query = xmlMemStrdup(ref->query); |
2079 if (ref->fragment != NULL) | 2001 if (ref->fragment != NULL) |
2080 res->fragment = xmlMemStrdup(ref->fragment); | 2002 res->fragment = xmlMemStrdup(ref->fragment); |
2081 | 2003 |
2082 /* | 2004 /* |
2083 * 4) If the authority component is defined, then the reference is a | 2005 * 4) If the authority component is defined, then the reference is a |
2084 * network-path and we skip to step 7. Otherwise, the reference | 2006 * network-path and we skip to step 7. Otherwise, the reference |
2085 * URI's authority is inherited from the base URI's authority | 2007 * URI's authority is inherited from the base URI's authority |
2086 * component, which will also be undefined if the URI scheme does not | 2008 * component, which will also be undefined if the URI scheme does not |
2087 * use an authority component. | 2009 * use an authority component. |
2088 */ | 2010 */ |
2089 if ((ref->authority != NULL) || (ref->server != NULL)) { | 2011 if ((ref->authority != NULL) || (ref->server != NULL)) { |
2090 if (ref->authority != NULL) | 2012 if (ref->authority != NULL) |
2091 res->authority = xmlMemStrdup(ref->authority); | 2013 res->authority = xmlMemStrdup(ref->authority); |
2092 else { | 2014 else { |
2093 res->server = xmlMemStrdup(ref->server); | 2015 res->server = xmlMemStrdup(ref->server); |
2094 if (ref->user != NULL) | 2016 if (ref->user != NULL) |
2095 res->user = xmlMemStrdup(ref->user); | 2017 res->user = xmlMemStrdup(ref->user); |
2096 res->port = ref->port;» » | 2018 res->port = ref->port; |
2097 } | 2019 } |
2098 if (ref->path != NULL) | 2020 if (ref->path != NULL) |
2099 res->path = xmlMemStrdup(ref->path); | 2021 res->path = xmlMemStrdup(ref->path); |
2100 goto step_7; | 2022 goto step_7; |
2101 } | 2023 } |
2102 if (bas->authority != NULL) | 2024 if (bas->authority != NULL) |
2103 res->authority = xmlMemStrdup(bas->authority); | 2025 res->authority = xmlMemStrdup(bas->authority); |
2104 else if (bas->server != NULL) { | 2026 else if (bas->server != NULL) { |
2105 res->server = xmlMemStrdup(bas->server); | 2027 res->server = xmlMemStrdup(bas->server); |
2106 if (bas->user != NULL) | 2028 if (bas->user != NULL) |
2107 res->user = xmlMemStrdup(bas->user); | 2029 res->user = xmlMemStrdup(bas->user); |
2108 » res->port = bas->port;» » | 2030 » res->port = bas->port; |
2109 } | 2031 } |
2110 | 2032 |
2111 /* | 2033 /* |
2112 * 5) If the path component begins with a slash character ("/"), then | 2034 * 5) If the path component begins with a slash character ("/"), then |
2113 * the reference is an absolute-path and we skip to step 7. | 2035 * the reference is an absolute-path and we skip to step 7. |
2114 */ | 2036 */ |
2115 if ((ref->path != NULL) && (ref->path[0] == '/')) { | 2037 if ((ref->path != NULL) && (ref->path[0] == '/')) { |
2116 res->path = xmlMemStrdup(ref->path); | 2038 res->path = xmlMemStrdup(ref->path); |
2117 goto step_7; | 2039 goto step_7; |
2118 } | 2040 } |
2119 | 2041 |
2120 | 2042 |
2121 /* | 2043 /* |
2122 * 6) If this step is reached, then we are resolving a relative-path | 2044 * 6) If this step is reached, then we are resolving a relative-path |
2123 * reference. The relative path needs to be merged with the base | 2045 * reference. The relative path needs to be merged with the base |
2124 * URI's path. Although there are many ways to do this, we will | 2046 * URI's path. Although there are many ways to do this, we will |
2125 * describe a simple method using a separate string buffer. | 2047 * describe a simple method using a separate string buffer. |
2126 * | 2048 * |
2127 * Allocate a buffer large enough for the result string. | 2049 * Allocate a buffer large enough for the result string. |
2128 */ | 2050 */ |
2129 len = 2; /* extra / and 0 */ | 2051 len = 2; /* extra / and 0 */ |
2130 if (ref->path != NULL) | 2052 if (ref->path != NULL) |
2131 len += strlen(ref->path); | 2053 len += strlen(ref->path); |
2132 if (bas->path != NULL) | 2054 if (bas->path != NULL) |
2133 len += strlen(bas->path); | 2055 len += strlen(bas->path); |
2134 res->path = (char *) xmlMallocAtomic(len); | 2056 res->path = (char *) xmlMallocAtomic(len); |
2135 if (res->path == NULL) { | 2057 if (res->path == NULL) { |
2136 » xmlGenericError(xmlGenericErrorContext, | 2058 xmlURIErrMemory("resolving URI against base\n"); |
2137 » » "xmlBuildURI: out of memory\n"); | |
2138 goto done; | 2059 goto done; |
2139 } | 2060 } |
2140 res->path[0] = 0; | 2061 res->path[0] = 0; |
2141 | 2062 |
2142 /* | 2063 /* |
2143 * a) All but the last segment of the base URI's path component is | 2064 * a) All but the last segment of the base URI's path component is |
2144 * copied to the buffer. In other words, any characters after the | 2065 * copied to the buffer. In other words, any characters after the |
2145 * last (right-most) slash character, if any, are excluded. | 2066 * last (right-most) slash character, if any, are excluded. |
2146 */ | 2067 */ |
2147 cur = 0; | 2068 cur = 0; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2373 * In base, count the number of '/' from the differing point | 2294 * In base, count the number of '/' from the differing point |
2374 */ | 2295 */ |
2375 if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */ | 2296 if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */ |
2376 for (; bptr[ix] != 0; ix++) { | 2297 for (; bptr[ix] != 0; ix++) { |
2377 if (bptr[ix] == '/') | 2298 if (bptr[ix] == '/') |
2378 nbslash++; | 2299 nbslash++; |
2379 } | 2300 } |
2380 } | 2301 } |
2381 len = xmlStrlen (uptr) + 1; | 2302 len = xmlStrlen (uptr) + 1; |
2382 } | 2303 } |
2383 | 2304 |
2384 if (nbslash == 0) { | 2305 if (nbslash == 0) { |
2385 if (uptr != NULL) | 2306 if (uptr != NULL) |
2386 /* exception characters from xmlSaveUri */ | 2307 /* exception characters from xmlSaveUri */ |
2387 val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,"); | 2308 val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,"); |
2388 goto done; | 2309 goto done; |
2389 } | 2310 } |
2390 | 2311 |
2391 /* | 2312 /* |
2392 * Allocate just enough space for the returned string - | 2313 * Allocate just enough space for the returned string - |
2393 * length of the remainder of the URI, plus enough space | 2314 * length of the remainder of the URI, plus enough space |
2394 * for the "../" groups, plus one for the terminator | 2315 * for the "../" groups, plus one for the terminator |
2395 */ | 2316 */ |
2396 val = (xmlChar *) xmlMalloc (len + 3 * nbslash); | 2317 val = (xmlChar *) xmlMalloc (len + 3 * nbslash); |
2397 if (val == NULL) { | 2318 if (val == NULL) { |
2398 » xmlGenericError(xmlGenericErrorContext, | 2319 xmlURIErrMemory("building relative URI\n"); |
2399 » » "xmlBuildRelativeURI: out of memory\n"); | |
2400 goto done; | 2320 goto done; |
2401 } | 2321 } |
2402 vptr = val; | 2322 vptr = val; |
2403 /* | 2323 /* |
2404 * Put in as many "../" as needed | 2324 * Put in as many "../" as needed |
2405 */ | 2325 */ |
2406 for (; nbslash>0; nbslash--) { | 2326 for (; nbslash>0; nbslash--) { |
2407 *vptr++ = '.'; | 2327 *vptr++ = '.'; |
2408 *vptr++ = '.'; | 2328 *vptr++ = '.'; |
2409 *vptr++ = '/'; | 2329 *vptr++ = '/'; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2441 if (bas != NULL) | 2361 if (bas != NULL) |
2442 xmlFreeURI (bas); | 2362 xmlFreeURI (bas); |
2443 | 2363 |
2444 return val; | 2364 return val; |
2445 } | 2365 } |
2446 | 2366 |
2447 /** | 2367 /** |
2448 * xmlCanonicPath: | 2368 * xmlCanonicPath: |
2449 * @path: the resource locator in a filesystem notation | 2369 * @path: the resource locator in a filesystem notation |
2450 * | 2370 * |
2451 * Constructs a canonic path from the specified path. | 2371 * Constructs a canonic path from the specified path. |
2452 * | 2372 * |
2453 * Returns a new canonic path, or a duplicate of the path parameter if the | 2373 * Returns a new canonic path, or a duplicate of the path parameter if the |
2454 * construction fails. The caller is responsible for freeing the memory occupied | 2374 * construction fails. The caller is responsible for freeing the memory occupied |
2455 * by the returned string. If there is insufficient memory available, or the | 2375 * by the returned string. If there is insufficient memory available, or the |
2456 * argument is NULL, the function returns NULL. | 2376 * argument is NULL, the function returns NULL. |
2457 */ | 2377 */ |
2458 #define IS_WINDOWS_PATH(p) » » » » » \ | 2378 #define IS_WINDOWS_PATH(p)» » » » » \ |
2459 ((p != NULL) && \ | 2379 ((p != NULL) && \ |
2460 (((p[0] >= 'a') && (p[0] <= 'z')) || \ | 2380 (((p[0] >= 'a') && (p[0] <= 'z')) || \ |
2461 ((p[0] >= 'A') && (p[0] <= 'Z'))) && \ | 2381 ((p[0] >= 'A') && (p[0] <= 'Z'))) && \ |
2462 (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\'))) | 2382 (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\'))) |
2463 xmlChar * | 2383 xmlChar * |
2464 xmlCanonicPath(const xmlChar *path) | 2384 xmlCanonicPath(const xmlChar *path) |
2465 { | 2385 { |
2466 /* | 2386 /* |
2467 * For Windows implementations, additional work needs to be done to | 2387 * For Windows implementations, additional work needs to be done to |
2468 * replace backslashes in pathnames with "forward slashes" | 2388 * replace backslashes in pathnames with "forward slashes" |
2469 */ | 2389 */ |
2470 #if defined(_WIN32) && !defined(__CYGWIN__) | 2390 #if defined(_WIN32) && !defined(__CYGWIN__) |
2471 int len = 0; | 2391 int len = 0; |
2472 int i = 0; | 2392 int i = 0; |
2473 xmlChar *p = NULL; | 2393 xmlChar *p = NULL; |
2474 #endif | 2394 #endif |
2475 xmlURIPtr uri; | 2395 xmlURIPtr uri; |
2476 xmlChar *ret; | 2396 xmlChar *ret; |
2477 const xmlChar *absuri; | 2397 const xmlChar *absuri; |
2478 | 2398 |
2479 if (path == NULL) | 2399 if (path == NULL) |
2480 return(NULL); | 2400 return(NULL); |
2481 | 2401 |
2482 /* sanitize filename starting with // so it can be used as URI */ | 2402 #if defined(_WIN32) |
| 2403 /* |
| 2404 * We must not change the backslashes to slashes if the the path |
| 2405 * starts with \\?\ |
| 2406 * Those paths can be up to 32k characters long. |
| 2407 * Was added specifically for OpenOffice, those paths can't be converted |
| 2408 * to URIs anyway. |
| 2409 */ |
| 2410 if ((path[0] == '\\') && (path[1] == '\\') && (path[2] == '?') && |
| 2411 (path[3] == '\\') ) |
| 2412 » return xmlStrdup((const xmlChar *) path); |
| 2413 #endif |
| 2414 |
| 2415 » /* sanitize filename starting with // so it can be used as URI */ |
2483 if ((path[0] == '/') && (path[1] == '/') && (path[2] != '/')) | 2416 if ((path[0] == '/') && (path[1] == '/') && (path[2] != '/')) |
2484 path++; | 2417 path++; |
2485 | 2418 |
2486 if ((uri = xmlParseURI((const char *) path)) != NULL) { | 2419 if ((uri = xmlParseURI((const char *) path)) != NULL) { |
2487 xmlFreeURI(uri); | 2420 xmlFreeURI(uri); |
2488 return xmlStrdup(path); | 2421 return xmlStrdup(path); |
2489 } | 2422 } |
2490 | 2423 |
2491 /* Check if this is an "absolute uri" */ | 2424 /* Check if this is an "absolute uri" */ |
2492 absuri = xmlStrstr(path, BAD_CAST "://"); | 2425 absuri = xmlStrstr(path, BAD_CAST "://"); |
(...skipping 26 matching lines...) Expand all Loading... |
2519 /* If successful, return the escaped string */ | 2452 /* If successful, return the escaped string */ |
2520 if (uri != NULL) { | 2453 if (uri != NULL) { |
2521 xmlFreeURI(uri); | 2454 xmlFreeURI(uri); |
2522 return escURI; | 2455 return escURI; |
2523 } | 2456 } |
2524 } | 2457 } |
2525 } | 2458 } |
2526 | 2459 |
2527 path_processing: | 2460 path_processing: |
2528 /* For Windows implementations, replace backslashes with 'forward slashes' */ | 2461 /* For Windows implementations, replace backslashes with 'forward slashes' */ |
2529 #if defined(_WIN32) && !defined(__CYGWIN__) | 2462 #if defined(_WIN32) && !defined(__CYGWIN__) |
2530 /* | 2463 /* |
2531 * Create a URI structure | 2464 * Create a URI structure |
2532 */ | 2465 */ |
2533 uri = xmlCreateURI(); | 2466 uri = xmlCreateURI(); |
2534 if (uri == NULL) { /* Guard against 'out of memory' */ | 2467 if (uri == NULL) { /* Guard against 'out of memory' */ |
2535 return(NULL); | 2468 return(NULL); |
2536 } | 2469 } |
2537 | 2470 |
2538 len = xmlStrlen(path); | 2471 len = xmlStrlen(path); |
2539 if ((len > 2) && IS_WINDOWS_PATH(path)) { | 2472 if ((len > 2) && IS_WINDOWS_PATH(path)) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2576 #endif | 2509 #endif |
2577 return(ret); | 2510 return(ret); |
2578 } | 2511 } |
2579 | 2512 |
2580 /** | 2513 /** |
2581 * xmlPathToURI: | 2514 * xmlPathToURI: |
2582 * @path: the resource locator in a filesystem notation | 2515 * @path: the resource locator in a filesystem notation |
2583 * | 2516 * |
2584 * Constructs an URI expressing the existing path | 2517 * Constructs an URI expressing the existing path |
2585 * | 2518 * |
2586 * Returns a new URI, or a duplicate of the path parameter if the | 2519 * Returns a new URI, or a duplicate of the path parameter if the |
2587 * construction fails. The caller is responsible for freeing the memory | 2520 * construction fails. The caller is responsible for freeing the memory |
2588 * occupied by the returned string. If there is insufficient memory available, | 2521 * occupied by the returned string. If there is insufficient memory available, |
2589 * or the argument is NULL, the function returns NULL. | 2522 * or the argument is NULL, the function returns NULL. |
2590 */ | 2523 */ |
2591 xmlChar * | 2524 xmlChar * |
2592 xmlPathToURI(const xmlChar *path) | 2525 xmlPathToURI(const xmlChar *path) |
2593 { | 2526 { |
2594 xmlURIPtr uri; | 2527 xmlURIPtr uri; |
2595 xmlURI temp; | 2528 xmlURI temp; |
2596 xmlChar *ret, *cal; | 2529 xmlChar *ret, *cal; |
2597 | 2530 |
2598 if (path == NULL) | 2531 if (path == NULL) |
2599 return(NULL); | 2532 return(NULL); |
2600 | 2533 |
2601 if ((uri = xmlParseURI((const char *) path)) != NULL) { | 2534 if ((uri = xmlParseURI((const char *) path)) != NULL) { |
2602 xmlFreeURI(uri); | 2535 xmlFreeURI(uri); |
2603 return xmlStrdup(path); | 2536 return xmlStrdup(path); |
2604 } | 2537 } |
2605 cal = xmlCanonicPath(path); | 2538 cal = xmlCanonicPath(path); |
2606 if (cal == NULL) | 2539 if (cal == NULL) |
2607 return(NULL); | 2540 return(NULL); |
2608 #if defined(_WIN32) && !defined(__CYGWIN__) | 2541 #if defined(_WIN32) && !defined(__CYGWIN__) |
2609 /* xmlCanonicPath can return an URI on Windows (is that the intended behavio
ur?) | 2542 /* xmlCanonicPath can return an URI on Windows (is that the intended behavio
ur?) |
2610 If 'cal' is a valid URI allready then we are done here, as continuing wou
ld make | 2543 If 'cal' is a valid URI allready then we are done here, as continuing wou
ld make |
2611 it invalid. */ | 2544 it invalid. */ |
2612 if ((uri = xmlParseURI((const char *) cal)) != NULL) { | 2545 if ((uri = xmlParseURI((const char *) cal)) != NULL) { |
2613 xmlFreeURI(uri); | 2546 xmlFreeURI(uri); |
2614 return cal; | 2547 return cal; |
2615 } | 2548 } |
2616 /* 'cal' can contain a relative path with backslashes. If that is processed | 2549 /* 'cal' can contain a relative path with backslashes. If that is processed |
2617 by xmlSaveURI, they will be escaped and the external entity loader machin
ery | 2550 by xmlSaveURI, they will be escaped and the external entity loader machin
ery |
2618 will fail. So convert them to slashes. Misuse 'ret' for walking. */ | 2551 will fail. So convert them to slashes. Misuse 'ret' for walking. */ |
2619 ret = cal; | 2552 ret = cal; |
2620 while (*ret != '\0') { | 2553 while (*ret != '\0') { |
2621 if (*ret == '\\') | 2554 if (*ret == '\\') |
2622 *ret = '/'; | 2555 *ret = '/'; |
2623 ret++; | 2556 ret++; |
2624 } | 2557 } |
2625 #endif | 2558 #endif |
2626 memset(&temp, 0, sizeof(temp)); | 2559 memset(&temp, 0, sizeof(temp)); |
2627 temp.path = (char *) cal; | 2560 temp.path = (char *) cal; |
2628 ret = xmlSaveUri(&temp); | 2561 ret = xmlSaveUri(&temp); |
2629 xmlFree(cal); | 2562 xmlFree(cal); |
2630 return(ret); | 2563 return(ret); |
2631 } | 2564 } |
2632 #define bottom_uri | 2565 #define bottom_uri |
2633 #include "elfgcchack.h" | 2566 #include "elfgcchack.h" |
OLD | NEW |