| 7824 | } |
| 7825 | |
| 7826 | static NAMED * |
| 7827 | lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) { |
| 7828 | size_t i; |
| 7829 | if (table->size == 0) { |
| 7830 | size_t tsize; |
| 7831 | if (! createSize) |
| 7832 | return NULL; |
| 7833 | table->power = INIT_POWER; |
| 7834 | /* table->size is a power of 2 */ |
| 7835 | table->size = (size_t)1 << INIT_POWER; |
| 7836 | tsize = table->size * sizeof(NAMED *); |
| 7837 | table->v = MALLOC(table->parser, tsize); |
| 7838 | if (! table->v) { |
| 7839 | table->size = 0; |
| 7840 | return NULL; |
| 7841 | } |
| 7842 | memset(table->v, 0, tsize); |
| 7843 | i = hash(parser, name) & ((unsigned long)table->size - 1); |
| 7844 | } else { |
| 7845 | unsigned long h = hash(parser, name); |
| 7846 | unsigned long mask = (unsigned long)table->size - 1; |
| 7847 | unsigned char step = 0; |
| 7848 | i = h & mask; |
| 7849 | while (table->v[i]) { |
| 7850 | if (keyeq(name, table->v[i]->name)) |
| 7851 | return table->v[i]; |
| 7852 | if (! step) |
| 7853 | step = PROBE_STEP(h, mask, table->power); |
| 7854 | i < step ? (i += table->size - step) : (i -= step); |
| 7855 | } |
| 7856 | if (! createSize) |
| 7857 | return NULL; |
| 7858 | |
| 7859 | /* check for overflow (table is half full) */ |
| 7860 | if (table->used >> (table->power - 1)) { |
| 7861 | unsigned char newPower = table->power + 1; |
| 7862 | |
| 7863 | /* Detect and prevent invalid shift */ |
| 7864 | if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) { |
| 7865 | return NULL; |
| 7866 | } |
| 7867 | |
| 7868 | size_t newSize = (size_t)1 << newPower; |
| 7869 | unsigned long newMask = (unsigned long)newSize - 1; |
| 7870 | |
| 7871 | /* Detect and prevent integer overflow */ |
| 7872 | if (newSize > (size_t)(-1) / sizeof(NAMED *)) { |
| 7873 | return NULL; |
| 7874 | } |
| 7875 | |
| 7876 | size_t tsize = newSize * sizeof(NAMED *); |
| 7877 | NAMED **newV = MALLOC(table->parser, tsize); |
| 7878 | if (! newV) |
| 7879 | return NULL; |
| 7880 | memset(newV, 0, tsize); |
| 7881 | for (i = 0; i < table->size; i++) |
| 7882 | if (table->v[i]) { |
| 7883 | unsigned long newHash = hash(parser, table->v[i]->name); |
no test coverage detected
searching dependent graphs…