Convert a string into a long long. Returns REDIS_OK if the string could be * parsed into a (non-overflowing) long long, REDIS_ERR otherwise. The value * will be set to the parsed value when appropriate. * * Note that this function demands that the string strictly represents * a long long: no spaces or other characters before or after the string * representing the number are accepted, nor zer
| 161 | * you can convert a string into a long long, and obtain back the string |
| 162 | * from the number without any loss in the string representation. */ |
| 163 | static int string2ll(const char *s, size_t slen, long long *value) { |
| 164 | const char *p = s; |
| 165 | size_t plen = 0; |
| 166 | int negative = 0; |
| 167 | unsigned long long v; |
| 168 | |
| 169 | if (plen == slen) |
| 170 | return REDIS_ERR; |
| 171 | |
| 172 | /* Special case: first and only digit is 0. */ |
| 173 | if (slen == 1 && p[0] == '0') { |
| 174 | if (value != NULL) *value = 0; |
| 175 | return REDIS_OK; |
| 176 | } |
| 177 | |
| 178 | if (p[0] == '-') { |
| 179 | negative = 1; |
| 180 | p++; plen++; |
| 181 | |
| 182 | /* Abort on only a negative sign. */ |
| 183 | if (plen == slen) |
| 184 | return REDIS_ERR; |
| 185 | } |
| 186 | |
| 187 | /* First digit should be 1-9, otherwise the string should just be 0. */ |
| 188 | if (p[0] >= '1' && p[0] <= '9') { |
| 189 | v = p[0]-'0'; |
| 190 | p++; plen++; |
| 191 | } else if (p[0] == '0' && slen == 1) { |
| 192 | *value = 0; |
| 193 | return REDIS_OK; |
| 194 | } else { |
| 195 | return REDIS_ERR; |
| 196 | } |
| 197 | |
| 198 | while (plen < slen && p[0] >= '0' && p[0] <= '9') { |
| 199 | if (v > (ULLONG_MAX / 10)) /* Overflow. */ |
| 200 | return REDIS_ERR; |
| 201 | v *= 10; |
| 202 | |
| 203 | if (v > (ULLONG_MAX - (p[0]-'0'))) /* Overflow. */ |
| 204 | return REDIS_ERR; |
| 205 | v += p[0]-'0'; |
| 206 | |
| 207 | p++; plen++; |
| 208 | } |
| 209 | |
| 210 | /* Return if not all bytes were used. */ |
| 211 | if (plen < slen) |
| 212 | return REDIS_ERR; |
| 213 | |
| 214 | if (negative) { |
| 215 | if (v > ((unsigned long long)(-(LLONG_MIN+1))+1)) /* Overflow. */ |
| 216 | return REDIS_ERR; |
| 217 | if (value != NULL) *value = -v; |
| 218 | } else { |
| 219 | if (v > LLONG_MAX) /* Overflow. */ |
| 220 | return REDIS_ERR; |
no outgoing calls
no test coverage detected