| 1143 | } |
| 1144 | |
| 1145 | bool control_conn_t::process_setenv() |
| 1146 | { |
| 1147 | using std::string; |
| 1148 | |
| 1149 | string envVar; |
| 1150 | typename string::size_type eq; |
| 1151 | |
| 1152 | constexpr int pkt_size = 4; |
| 1153 | char badreqRep[] = { (char)cp_rply::BADREQ }; |
| 1154 | char okRep[] = { (char)cp_rply::ACK }; |
| 1155 | |
| 1156 | if (rbuf.get_length() < pkt_size) { |
| 1157 | chklen = pkt_size; |
| 1158 | return true; |
| 1159 | } |
| 1160 | |
| 1161 | envvar_len_t envvar_len; |
| 1162 | rbuf.extract(&envvar_len, 1, sizeof(envvar_len)); |
| 1163 | if (envvar_len <= 0 || envvar_len > (1024 - 3)) { |
| 1164 | goto badreq; |
| 1165 | } |
| 1166 | chklen = envvar_len + 1 + sizeof(envvar_len); // packet type + (2 byte) length + envvar |
| 1167 | |
| 1168 | if (rbuf.get_length() < chklen) { |
| 1169 | // packet not complete yet; read more |
| 1170 | return true; |
| 1171 | } |
| 1172 | |
| 1173 | envVar = rbuf.extract_string(3, envvar_len); |
| 1174 | |
| 1175 | eq = envVar.find('='); |
| 1176 | if (eq == envVar.npos) { |
| 1177 | // Unset the env var |
| 1178 | main_env.undefine_var(std::move(envVar), true); |
| 1179 | } |
| 1180 | else if (eq) { |
| 1181 | // Regular set |
| 1182 | main_env.set_var(std::move(envVar), true); |
| 1183 | } |
| 1184 | else { |
| 1185 | // At the beginning of the string |
| 1186 | goto badreq; |
| 1187 | } |
| 1188 | |
| 1189 | // Success response |
| 1190 | if (!queue_packet(okRep, 1)) return false; |
| 1191 | |
| 1192 | // Clear the packet from the buffer |
| 1193 | rbuf.consume(chklen); |
| 1194 | chklen = 0; |
| 1195 | return true; |
| 1196 | |
| 1197 | badreq: |
| 1198 | // Queue error response / mark connection bad |
| 1199 | if (!queue_packet(badreqRep, 1)) return false; |
| 1200 | bad_conn_close = true; |
| 1201 | return true; |
| 1202 | } |
nothing calls this directly
no test coverage detected