----------------------------------------------------------------------------- Purpose: Internal implementation of encode, works in the strict RFC manner, or with spaces turned to + like HTML form encoding. -----------------------------------------------------------------------------
| 247 | // with spaces turned to + like HTML form encoding. |
| 248 | //----------------------------------------------------------------------------- |
| 249 | void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, bool bUsePlusForSpace ) |
| 250 | { |
| 251 | //AssertMsg( nDestLen > 3*nSourceLen, "Target buffer for V_URLEncode should be 3x source length, plus one for terminating null\n" ); |
| 252 | |
| 253 | int iDestPos = 0; |
| 254 | for ( int i=0; i < nSourceLen; ++i ) |
| 255 | { |
| 256 | // worst case we need 3 additional chars |
| 257 | if( (iDestPos+3) > nDestLen ) |
| 258 | { |
| 259 | pchDest[0] = '\0'; |
| 260 | // AssertMsg( false, "Target buffer too short\n" ); |
| 261 | return; |
| 262 | } |
| 263 | |
| 264 | // We allow only a-z, A-Z, 0-9, period, underscore, and hyphen to pass through unescaped. |
| 265 | // These are the characters allowed by both the original RFC 1738 and the latest RFC 3986. |
| 266 | // Current specs also allow '~', but that is forbidden under original RFC 1738. |
| 267 | if ( !( pchSource[i] >= 'a' && pchSource[i] <= 'z' ) && !( pchSource[i] >= 'A' && pchSource[i] <= 'Z' ) && !(pchSource[i] >= '0' && pchSource[i] <= '9' ) |
| 268 | && pchSource[i] != '-' && pchSource[i] != '_' && pchSource[i] != '.' |
| 269 | ) |
| 270 | { |
| 271 | if ( bUsePlusForSpace && pchSource[i] == ' ' ) |
| 272 | { |
| 273 | pchDest[iDestPos++] = '+'; |
| 274 | } |
| 275 | else |
| 276 | { |
| 277 | pchDest[iDestPos++] = '%'; |
| 278 | uint8_t iValue = pchSource[i]; |
| 279 | if ( iValue == 0 ) |
| 280 | { |
| 281 | pchDest[iDestPos++] = '0'; |
| 282 | pchDest[iDestPos++] = '0'; |
| 283 | } |
| 284 | else |
| 285 | { |
| 286 | char cHexDigit1 = cIntToHexDigit( iValue % 16 ); |
| 287 | iValue /= 16; |
| 288 | char cHexDigit2 = cIntToHexDigit( iValue ); |
| 289 | pchDest[iDestPos++] = cHexDigit2; |
| 290 | pchDest[iDestPos++] = cHexDigit1; |
| 291 | } |
| 292 | } |
| 293 | } |
| 294 | else |
| 295 | { |
| 296 | pchDest[iDestPos++] = pchSource[i]; |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | if( (iDestPos+1) > nDestLen ) |
| 301 | { |
| 302 | pchDest[0] = '\0'; |
| 303 | //AssertMsg( false, "Target buffer too short to terminate\n" ); |
| 304 | return; |
| 305 | } |
| 306 |
no test coverage detected