Я просматривал исходный код SQLite, когда я натолкнулся на эту функцию, начиная с строки 387
в shell.c
.Границы указателя и арифметика указателя в исходном коде SQLite
Исходный код: https://www.sqlite.org/download.html
Функция в вопросе:
/*
** Determines if a string is a number of not.
*/
static int isNumber(const char *z, int *realnum){
if(*z=='-' || *z=='+') z++;
if(!IsDigit(*z)){
return 0;
}
z++;
if(realnum) *realnum = 0;
while(IsDigit(*z)){ z++; }
if(*z=='.'){
z++;
if(!IsDigit(*z)) return 0;
while(IsDigit(*z)){ z++; }
if(realnum) *realnum = 1;
}
if(*z=='e' || *z=='E'){
z++;
if(*z=='+' || *z=='-') z++;
if(!IsDigit(*z)) return 0;
while(IsDigit(*z)){ z++; }
if(realnum) *realnum = 1;
}
return *z==0;
}
Примечание: IsDigit макрос, который подает неподписанный символ в isdigit, определенной в CType.
#define IsDigit(X) isdigit((unsigned char)X)
Функция и использование указателя имеет смысл для меня, однако, первые две строки заставляет меня полагать, что они могут быть использованы ненадлежащим образом на основе моего понимания.
Они используют арифметику указателя для перемешивания по строке.
if(*z=='-' || *z=='+') z++;
Если символ в первой позиции указателя является «-» или «+», переместите указатель на одну позиции. Однако это, похоже, не учитывает, если строка, переданная в функцию, имеет только один символ, который является символом «-» или «+».
if(!IsDigit(*z)){
Когда «г» разыменовывается, не это повреждено/незаконный доступ к памяти, потому что она выходит из рамки указателя, или есть что-то за кулисами с арифметикой указателей, что останавливает это происходило?
SQLite используется на * сотнях миллионов * iOS и Android-устройствах каждый день. Скорее всего, вы не обнаружили ранее не обнаруженную ошибку при их основном анализе чисел. –