* xmlXPtrEvalChildSeq: * @ctxt: the XPointer Parser context * @name: a possible ID name of the child sequence * * ChildSeq ::= '/1' ('/' [0-9]*)* * | Name ('/' [0-9]*)+ * * Parse and evaluate a Child Sequence. This routine also handle the * case of a Bare Name used to get a document ID. */
| 1173 | * case of a Bare Name used to get a document ID. |
| 1174 | */ |
| 1175 | static void |
| 1176 | xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) { |
| 1177 | /* |
| 1178 | * XPointer don't allow by syntax to address in multirooted trees |
| 1179 | * this might prove useful in some cases, warn about it. |
| 1180 | */ |
| 1181 | if ((name == NULL) && (CUR == '/') && (NXT(1) != '1')) { |
| 1182 | xmlXPtrErr(ctxt, XML_XPTR_CHILDSEQ_START, |
| 1183 | "warning: ChildSeq not starting by /1\n", NULL); |
| 1184 | } |
| 1185 | |
| 1186 | if (name != NULL) { |
| 1187 | valuePush(ctxt, xmlXPathNewString(name)); |
| 1188 | xmlFree(name); |
| 1189 | xmlXPathIdFunction(ctxt, 1); |
| 1190 | CHECK_ERROR; |
| 1191 | } |
| 1192 | |
| 1193 | while (CUR == '/') { |
| 1194 | int child = 0, overflow = 0; |
| 1195 | NEXT; |
| 1196 | |
| 1197 | while ((CUR >= '0') && (CUR <= '9')) { |
| 1198 | int d = CUR - '0'; |
| 1199 | if (child > INT_MAX / 10) |
| 1200 | overflow = 1; |
| 1201 | else |
| 1202 | child *= 10; |
| 1203 | if (child > INT_MAX - d) |
| 1204 | overflow = 1; |
| 1205 | else |
| 1206 | child += d; |
| 1207 | NEXT; |
| 1208 | } |
| 1209 | if (overflow) |
| 1210 | child = 0; |
| 1211 | xmlXPtrGetChildNo(ctxt, child); |
| 1212 | } |
| 1213 | } |
| 1214 | |
| 1215 | |
| 1216 | /** |
no test coverage detected