| 169 | |
| 170 | |
| 171 | inline RARPPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,RARPPM_STATE* p1) |
| 172 | { |
| 173 | RARPPM_STATE UpState; |
| 174 | RARPPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor; |
| 175 | RARPPM_STATE * p, * ps[MAX_O], ** pps=ps; |
| 176 | if ( !Skip ) |
| 177 | { |
| 178 | *pps++ = FoundState; |
| 179 | if ( !pc->Suffix ) |
| 180 | goto NO_LOOP; |
| 181 | } |
| 182 | if ( p1 ) |
| 183 | { |
| 184 | p=p1; |
| 185 | pc=pc->Suffix; |
| 186 | goto LOOP_ENTRY; |
| 187 | } |
| 188 | do |
| 189 | { |
| 190 | pc=pc->Suffix; |
| 191 | if (pc->NumStats != 1) |
| 192 | { |
| 193 | if ((p=pc->U.Stats)->Symbol != FoundState->Symbol) |
| 194 | do |
| 195 | { |
| 196 | p++; |
| 197 | } while (p->Symbol != FoundState->Symbol); |
| 198 | } |
| 199 | else |
| 200 | p=&(pc->OneState); |
| 201 | LOOP_ENTRY: |
| 202 | if (p->Successor != UpBranch) |
| 203 | { |
| 204 | pc=p->Successor; |
| 205 | break; |
| 206 | |
| 207 | } |
| 208 | // We ensure that PPM order input parameter does not exceed MAX_O (64), |
| 209 | // so we do not really need this check and added it for extra safety. |
| 210 | // See CVE-2017-17969 for details. |
| 211 | if (pps>=ps+ASIZE(ps)) |
| 212 | return NULL; |
| 213 | |
| 214 | *pps++ = p; |
| 215 | } while ( pc->Suffix ); |
| 216 | NO_LOOP: |
| 217 | if (pps == ps) |
| 218 | return pc; |
| 219 | UpState.Symbol=*(byte*) UpBranch; |
| 220 | UpState.Successor=(RARPPM_CONTEXT*) (((byte*) UpBranch)+1); |
| 221 | if (pc->NumStats != 1) |
| 222 | { |
| 223 | if ((byte*) pc <= SubAlloc.pText) |
| 224 | return(NULL); |
| 225 | if ((p=pc->U.Stats)->Symbol != UpState.Symbol) |
| 226 | do |
| 227 | { |
| 228 | p++; |
nothing calls this directly
no test coverage detected