Blender V4.3
GHOST_PathUtils.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2010 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cassert>
10#include <cctype>
11#include <cstdio>
12#include <cstdlib>
13#include <cstring>
14
15#include "GHOST_Debug.hh"
16#include "GHOST_PathUtils.hh"
17#include "GHOST_Types.h"
18
19/* Based on: https://stackoverflow.com/a/2766963/432509 */
20
23 STATE_SEARCH = 0,
25 STATE_CONVERTING
26};
27
28void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src, const int buf_src_len)
29{
30 GHOST_ASSERT(strnlen(buf_src, buf_src_len) == buf_src_len, "Incorrect length");
31
32 DecodeState_e state = STATE_SEARCH;
33 uint ascii_character;
34
35 memset(buf_dst, 0, buf_dst_size);
36
37 for (uint i = 0; i < buf_src_len; i++) {
38 switch (state) {
39 case STATE_SEARCH: {
40 if (buf_src[i] != '%') {
41 strncat(buf_dst, &buf_src[i], 1);
42 assert(int(strlen(buf_dst)) < buf_dst_size);
43 break;
44 }
45
46 /* We are now converting. */
47 state = STATE_CONVERTING;
48 break;
49 }
50 case STATE_CONVERTING: {
51 /* Create a buffer to hold the hex. For example, if `%20`,
52 * this buffer would hold 20 (in ASCII). */
53 char temp_num_buf[3];
54
55 /* Conversion complete (i.e. don't convert again next iteration). */
56 state = STATE_SEARCH;
57
58 /* Ensure both characters are hexadecimal. */
59 bool both_digits = true;
60 for (int j = 0; j < 2; j++) {
61 /* `isxdigit` serves to early null terminate the string too. */
62 const char hex_char = buf_src[i + j];
63 if (!isxdigit(hex_char)) {
64 both_digits = false;
65 break;
66 }
67 temp_num_buf[j] = hex_char;
68 }
69 if (!both_digits) {
70 break;
71 }
72 /* Convert two hexadecimal characters into one character. */
73 temp_num_buf[2] = '\0';
74 sscanf(temp_num_buf, "%x", &ascii_character);
75
76 /* Ensure we aren't going to overflow. */
77 assert(int(strlen(buf_dst)) < buf_dst_size);
78
79 /* Concatenate this character onto the output. */
80 strncat(buf_dst, (char *)&ascii_character, 1);
81
82 /* Skip the next character. */
83 i++;
84 break;
85 }
86 }
87 }
88}
89
90char *GHOST_URL_decode_alloc(const char *buf_src, const int buf_src_len)
91{
92 /* Assume one character of encoded URL can be expanded to 4 chars max. */
93 const size_t decoded_size_max = 4 * buf_src_len + 1;
94 char *buf_dst = (char *)malloc(decoded_size_max);
95 GHOST_URL_decode(buf_dst, decoded_size_max, buf_src, buf_src_len);
96 const size_t decoded_size = strlen(buf_dst) + 1;
97 if (decoded_size != decoded_size_max) {
98 char *buf_dst_trim = (char *)malloc(decoded_size);
99 memcpy(buf_dst_trim, buf_dst, decoded_size);
100 free(buf_dst);
101 buf_dst = buf_dst_trim;
102 }
103 return buf_dst;
104}
void BLI_kdtree_nd_ free(KDTree *tree)
unsigned int uint
#define GHOST_ASSERT(x, info)
void GHOST_URL_decode(char *buf_dst, int buf_dst_size, const char *buf_src, const int buf_src_len)
enum DecodeState_e { STATE_SEARCH=0, STATE_CONVERTING } DecodeState_e
char * GHOST_URL_decode_alloc(const char *buf_src, const int buf_src_len)
static ulong state[N]