| 1082 | } |
| 1083 | |
| 1084 | static enum get_oid_result get_oid_1(struct repository *r, |
| 1085 | const char *name, int len, |
| 1086 | struct object_id *oid, |
| 1087 | unsigned lookup_flags) |
| 1088 | { |
| 1089 | int ret, has_suffix; |
| 1090 | const char *cp; |
| 1091 | |
| 1092 | /* |
| 1093 | * "name~3" is "name^^^", "name~" is "name~1", and "name^" is "name^1". |
| 1094 | */ |
| 1095 | has_suffix = 0; |
| 1096 | for (cp = name + len - 1; name <= cp; cp--) { |
| 1097 | int ch = *cp; |
| 1098 | if ('0' <= ch && ch <= '9') |
| 1099 | continue; |
| 1100 | if (ch == '~' || ch == '^') |
| 1101 | has_suffix = ch; |
| 1102 | break; |
| 1103 | } |
| 1104 | |
| 1105 | if (has_suffix) { |
| 1106 | unsigned int num = 0; |
| 1107 | int len1 = cp - name; |
| 1108 | cp++; |
| 1109 | while (cp < name + len) { |
| 1110 | unsigned int digit = *cp++ - '0'; |
| 1111 | if (unsigned_mult_overflows(num, 10)) |
| 1112 | return MISSING_OBJECT; |
| 1113 | num *= 10; |
| 1114 | if (unsigned_add_overflows(num, digit)) |
| 1115 | return MISSING_OBJECT; |
| 1116 | num += digit; |
| 1117 | } |
| 1118 | if (!num && len1 == len - 1) |
| 1119 | num = 1; |
| 1120 | else if (num > INT_MAX) |
| 1121 | return MISSING_OBJECT; |
| 1122 | if (has_suffix == '^') |
| 1123 | return get_parent(r, name, len1, oid, num); |
| 1124 | /* else if (has_suffix == '~') -- goes without saying */ |
| 1125 | return get_nth_ancestor(r, name, len1, oid, num); |
| 1126 | } |
| 1127 | |
| 1128 | ret = peel_onion(r, name, len, oid, lookup_flags); |
| 1129 | if (!ret) |
| 1130 | return FOUND; |
| 1131 | |
| 1132 | ret = get_oid_basic(r, name, len, oid, lookup_flags); |
| 1133 | if (!ret) |
| 1134 | return FOUND; |
| 1135 | |
| 1136 | /* It could be describe output that is "SOMETHING-gXXXX" */ |
| 1137 | ret = get_describe_name(r, name, len, oid); |
| 1138 | if (!ret) |
| 1139 | return FOUND; |
| 1140 | |
| 1141 | return get_short_oid(r, name, len, oid, lookup_flags); |
no test coverage detected