static void stuff_stack_trace(const jrd_req* request) { Firebird::string sTrace; bool isEmpty = true; for (const jrd_req* req = request; req; req = req->req_caller) { const JrdStatement* statement = req->getStatement(); Firebird::string name; if (statement->triggerName.length()) { name = "At trigger '"; name += statement->triggerName.c_str(); } else if (statement->procedure) { name = statement->parentStatement ? "At sub procedure '" : "At procedure '"; name += statement->procedure->getName().toString().c_str(); } else if (statement->function) { name = statement->parentStatement ? "At sub function '" : "At function '"; name += statement->function->getName().toString().c_str(); } if (! name.isEmpty()) { name.trim(); if (sTrace.length() + name.length() + 2 > MAX_STACK_TRACE) break; if (isEmpty) { isEmpty = false; sTrace += name + "'"; } else { sTrace += "\n" + name + "'"; } if (req->req_src_line) { Firebird::string src_info; src_info.printf(" line: %"ULONGFORMAT", col: %"ULONGFORMAT, req->req_src_line, req->req_src_column); if (sTrace.length() + src_info.length() > MAX_STACK_TRACE) break; sTrace += src_info; } } } if (!isEmpty) ERR_post_nothrow(Arg::Gds(isc_stack_trace) << Arg::Str(sTrace)); }
/** callRemoteServiceManager @brief Calls service manager to execute command, specified in userInfo @param status @param handle @param userInfo @param outputFunction @param functionArg **/ void callRemoteServiceManager(ISC_STATUS* status, isc_svc_handle handle, Auth::UserData& userData, Firebird::IListUsers* callback) { char spb_buffer[1024]; char* spb = spb_buffer; const int op = userData.op; if (op != Auth::DIS_OPER && op != Auth::OLD_DIS_OPER && op != Auth::MAP_SET_OPER && op != Auth::MAP_DROP_OPER && !userData.user.entered()) { status[0] = isc_arg_gds; status[1] = isc_gsec_switches_error; status[2] = isc_arg_end; return; } switch (op) { case Auth::ADD_OPER: stuffSpbByte(spb, isc_action_svc_add_user); userInfoToSpb(spb, userData); break; case Auth::MOD_OPER: stuffSpbByte(spb, isc_action_svc_modify_user); userInfoToSpb(spb, userData); break; case Auth::DEL_OPER: stuffSpbByte(spb, isc_action_svc_delete_user); stuffSpb2(spb, isc_spb_sec_username, userData.user.get()); if (userData.role.entered()) { stuffSpb2(spb, isc_spb_sql_role_name, userData.role.get()); } break; case Auth::DIS_OPER: case Auth::OLD_DIS_OPER: { char usersDisplayTag = 0; checkServerUsersVersion(handle, usersDisplayTag); stuffSpbByte(spb, usersDisplayTag); } if (userData.user.entered()) { stuffSpb2(spb, isc_spb_sec_username, userData.user.get()); } if (userData.role.entered()) { stuffSpb2(spb, isc_spb_sql_role_name, userData.role.get()); } break; case Auth::MAP_SET_OPER: stuffSpbByte(spb, isc_action_svc_set_mapping); break; case Auth::MAP_DROP_OPER: stuffSpbByte(spb, isc_action_svc_drop_mapping); break; default: status[0] = isc_arg_gds; status[1] = isc_gsec_switches_error; status[2] = isc_arg_end; return; } if (userData.database.entered()) { stuffSpb2(spb, isc_spb_dbname, userData.database.get()); } fb_assert((size_t)(spb - spb_buffer) <= sizeof(spb_buffer)); if (isc_service_start(status, &handle, 0, static_cast<USHORT>(spb - spb_buffer), spb_buffer) != 0) { return; } spb = spb_buffer; stuffSpbByte(spb, isc_info_svc_timeout); stuffSpbShort(spb, 4); stuffSpbLong(spb, 10); char resultBuffer[RESULT_BUF_SIZE + 4]; Firebird::string text; ISC_STATUS_ARRAY temp_status; ISC_STATUS* local_status = status[1] ? temp_status : status; fb_utils::init_status(local_status); if (op == Auth::DIS_OPER || op == Auth::OLD_DIS_OPER) { const char request[] = {isc_info_svc_get_users}; int startQuery = 0; Auth::StackUserData uData; for (;;) { isc_resv_handle reserved = 0; isc_service_query(local_status, &handle, &reserved, static_cast<USHORT>(spb - spb_buffer), spb_buffer, sizeof(request), request, RESULT_BUF_SIZE - startQuery, &resultBuffer[startQuery]); if (local_status[1]) { return; } startQuery = typeBuffer(local_status, resultBuffer, startQuery, uData, callback, text); if (startQuery < 0) { break; } } if (uData.user.get()[0] && callback) { LocalStatus status; CheckStatusWrapper statusWrapper(&status); setAttr(&statusWrapper, &uData); check(&statusWrapper); callback->list(&statusWrapper, &uData); check(&statusWrapper); } } else { const char request = isc_info_svc_line; for (;;) { isc_resv_handle reserved = 0; isc_service_query(local_status, &handle, &reserved, 0, NULL, 1, &request, RESULT_BUF_SIZE, resultBuffer); if (local_status[1]) { return; } char *p = resultBuffer; if (*p++ == isc_info_svc_line) { FB_SIZE_T len = static_cast<FB_SIZE_T>(isc_vax_integer(p, sizeof(USHORT))); p += sizeof(USHORT); if (len > RESULT_BUF_SIZE) { len = RESULT_BUF_SIZE; } if (!len) { if (*p == isc_info_data_not_ready) continue; if (*p == isc_info_end) break; } p[len] = 0; text += p; } } } if (! text.isEmpty()) { local_status[0] = isc_arg_interpreted; // strdup - memory leak in case of errors local_status[1] = reinterpret_cast<ISC_STATUS>(strdup(text.c_str())); local_status[2] = isc_arg_end; } }
SINT64 ConfigFile::Parameter::asInteger() const { if (value.isEmpty()) return 0; SINT64 ret = 0; int sign = 1; int state = 1; // 1 - sign, 2 - numbers, 3 - multiplier Firebird::string trimmed = value; trimmed.trim(" \t"); if (trimmed.isEmpty()) return 0; const char* ch = trimmed.c_str(); for (; *ch; ch++) switch (*ch) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (state > 2) return 0; state = 2; ret = ret * 10 + (*ch - '0'); break; case '-': if (state > 1) return 0; sign = -sign; break; case ' ': case '\t': if (state == 1) break; return 0; case 'k': case 'K': if (state != 2) return 0; state = 3; ret = ret * 1024; break; case 'm': case 'M': if (state != 2) return 0; state = 3; ret = ret * 1024 * 1024; break; case 'g': case 'G': if (state != 2) return 0; state = 3; ret = ret * 1024 * 1024 * 1024; break; default: return 0; }; return sign * ret; }
void EVL_validate(thread_db* tdbb, const Item& item, const ItemInfo* itemInfo, dsc* desc, bool null) { /************************************** * * E V L _ v a l i d a t e * ************************************** * * Functional description * Validate argument/variable for not null and check constraint * **************************************/ if (itemInfo == NULL) return; jrd_req* request = tdbb->getRequest(); bool err = false; if (null && !itemInfo->nullable) err = true; const char* value = NULL_STRING_MARK; VaryStr<128> temp; MapFieldInfo::ValueType fieldInfo; if (!err && itemInfo->fullDomain && request->getStatement()->mapFieldInfo.get(itemInfo->field, fieldInfo) && fieldInfo.validationExpr) { if (desc && null) desc->dsc_flags |= DSC_null; const bool desc_is_null = !desc || (desc->dsc_flags & DSC_null); request->req_domain_validation = desc; const USHORT flags = request->req_flags; if (!fieldInfo.validationExpr->execute(tdbb, request) && !(request->req_flags & req_null)) { const USHORT length = desc_is_null ? 0 : MOV_make_string(desc, ttype_dynamic, &value, &temp, sizeof(temp) - 1); if (desc_is_null) value = NULL_STRING_MARK; else if (!length) value = ""; else const_cast<char*>(value)[length] = 0; // safe cast - data is on our local stack err = true; } request->req_flags = flags; } Firebird::string s; if (err) { ISC_STATUS status = isc_not_valid_for_var; const char* arg; if (item.type == Item::TYPE_CAST) { status = isc_not_valid_for; arg = "CAST"; } else { if (itemInfo->name.isEmpty()) { int index = item.index + 1; status = isc_not_valid_for; if (item.type == Item::TYPE_VARIABLE) { const jrd_prc* procedure = request->getStatement()->procedure; if (procedure) { if (index <= int(procedure->getOutputFields().getCount())) s.printf("output parameter number %d", index); else { s.printf("variable number %d", index - int(procedure->getOutputFields().getCount())); } } else s.printf("variable number %d", index); } else if (item.type == Item::TYPE_PARAMETER && item.subType == 0) s.printf("input parameter number %d", (index - 1) / 2 + 1); else if (item.type == Item::TYPE_PARAMETER && item.subType == 1) s.printf("output parameter number %d", index); if (s.isEmpty()) arg = UNKNOWN_STRING_MARK; else arg = s.c_str(); } else arg = itemInfo->name.c_str(); } ERR_post(Arg::Gds(status) << Arg::Str(arg) << Arg::Str(value)); } }