Check if any of the provided prefixes collide with one another or * with an existing prefix for the client. A collision is defined as two * prefixes that will emit an invalidation for the same key. If no prefix * collision is found, 1 is return, otherwise 0 is returned and the client * has an error emitted describing the error. */
| 110 | * collision is found, 1 is return, otherwise 0 is returned and the client |
| 111 | * has an error emitted describing the error. */ |
| 112 | int checkPrefixCollisionsOrReply(client *c, robj **prefixes, size_t numprefix) { |
| 113 | for (size_t i = 0; i < numprefix; i++) { |
| 114 | /* Check input list has no overlap with existing prefixes. */ |
| 115 | if (c->client_tracking_prefixes) { |
| 116 | raxIterator ri; |
| 117 | raxStart(&ri,c->client_tracking_prefixes); |
| 118 | raxSeek(&ri,"^",NULL,0); |
| 119 | while(raxNext(&ri)) { |
| 120 | if (stringCheckPrefix(ri.key,ri.key_len, |
| 121 | (unsigned char*)ptrFromObj(prefixes[i]),sdslen(szFromObj(prefixes[i])))) |
| 122 | { |
| 123 | sds collision = sdsnewlen(ri.key,ri.key_len); |
| 124 | addReplyErrorFormat(c, |
| 125 | "Prefix '%s' overlaps with an existing prefix '%s'. " |
| 126 | "Prefixes for a single client must not overlap.", |
| 127 | (unsigned char *)ptrFromObj(prefixes[i]), |
| 128 | (unsigned char *)collision); |
| 129 | sdsfree(collision); |
| 130 | raxStop(&ri); |
| 131 | return 0; |
| 132 | } |
| 133 | } |
| 134 | raxStop(&ri); |
| 135 | } |
| 136 | /* Check input has no overlap with itself. */ |
| 137 | for (size_t j = i + 1; j < numprefix; j++) { |
| 138 | if (stringCheckPrefix((unsigned char*)ptrFromObj(prefixes[i]),sdslen(szFromObj(prefixes[i])), |
| 139 | (unsigned char*)ptrFromObj(prefixes[j]),sdslen(szFromObj(prefixes[j])))) |
| 140 | { |
| 141 | addReplyErrorFormat(c, |
| 142 | "Prefix '%s' overlaps with another provided prefix '%s'. " |
| 143 | "Prefixes for a single client must not overlap.", |
| 144 | (unsigned char *)ptrFromObj(prefixes[i]), |
| 145 | (unsigned char *)ptrFromObj(prefixes[j])); |
| 146 | return i; |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | return 1; |
| 151 | } |
| 152 | |
| 153 | /* Set the client 'c' to track the prefix 'prefix'. If the client 'c' is |
| 154 | * already registered for the specified prefix, no operation is performed. */ |
no test coverage detected