Skip to content
Permalink
Browse files

use [] instead of "" in exceptions to avoid JSON escape

  • Loading branch information
Arnaud Bouchez
Arnaud Bouchez committed Jan 29, 2020
1 parent 6dfce05 commit f3e777d239bf3282d5fb70f536ffdd88afe24134
@@ -959,12 +959,12 @@ procedure TDDDDaemon.ExecuteCommandLine(ForceRun: boolean);
end
else begin
error := GetLastError;
msg := FormatUTF8('Error % "%" occured with',
msg := FormatUTF8('Error % [%] occured with',
[error, StringToUTF8(SysErrorMessage(error))]);
TextColor(ccLightRed);
ExitCode := 1; // notify error to caller batch
end;
msg := FormatUTF8('% "%" (%) on Service "%"',
msg := FormatUTF8('% [%] (%) on Service [%]',
[msg, param, cmdText, fSettings.ServiceName]);
writeln(msg);
AppendToTextFile(ExeVersion.User + ' ' +msg,
@@ -205,7 +205,7 @@ function TDDDAuthenticationAbstract.ChallengeSelectFinal(
fLogged := true;
CqrsSetResult(cqrsSuccess,result);
end else
CqrsSetResultMsg(cqrsBadRequest,'Wrong Password for "%"',[fChallengeLogonName],result);
CqrsSetResultMsg(cqrsBadRequest,'Wrong Password for [%]',[fChallengeLogonName],result);
fChallengeNonce := '';
fChallengeLogonName := '';
end;
@@ -425,7 +425,7 @@ function TDDDEmailValidationService.StartEmailValidation(
msg := Template.ComputeMessage(context,aTemplate.FileName);
if msg='' then
CqrsSetResultMsg(cqrsInvalidContent,
'Impossible to render template "%"',[aTemplate.FileName],result) else
'Impossible to render template [%]',[aTemplate.FileName],result) else
if EMailer.SendEmail(TRawUTF8DynArrayFrom([aEmail]),
aTemplate.SenderEmail,aTemplate.Subject,'',msg)=cqrsSuccess then
if Rest.AddOrUpdate(EmailValidation)=0 then
@@ -358,7 +358,7 @@ procedure TSMTPServerSocketConnection.Expect(const Answer: RawByteString);
readln(fSocket.SockIn^,Res);
until (Length(Res)<4)or(Res[4]<>'-');
if not IdemPChar(pointer(Res),pointer(Answer)) then
raise ECrtSocket.CreateFmt('returned "%s", expecting "%s"',[Res,Answer]);
raise ECrtSocket.CreateFmt('returned [%s], expecting [%s]',[Res,Answer]);
end;

procedure TSMTPServerSocketConnection.Exec(const Command,
@@ -406,8 +406,8 @@ function TSMTPServerSocketConnection.SendEmail(
result := ''; // for success
except
on E: Exception do
result := FormatUTF8('%.SendEmail(%:%) server failure "%" (%)',
[self,fOwner.Address,fOwner.Port,E.Message,E]);
result := FormatUTF8('%.SendEmail(%:%) server failure % [%]',
[self,fOwner.Address,fOwner.Port,E,E.Message]);
end;
end;

// check that this property is not an ID/RowID (handled separately)
if IsRowID(pointer(aItem.Name)) and not (pilAllowIDFields in fOptions) then
raise EModelException.CreateUTF8(
'%.Add: % should not include a "%" published property',[self,fTable,aItem.Name]);
'%.Add: % should not include a [%] published property',[self,fTable,aItem.Name]);
// check that this property name is not already defined
for f := 0 to fCount-1 do
if IdemPropNameU(fList[f].Name,aItem.Name) then
raise EModelException.CreateUTF8('%.Add: % has duplicated name "%"',
raise EModelException.CreateUTF8('%.Add: % has duplicated name [%]',
[self,fTable,aItem.Name]);
// add to the internal list
result := fCount;
begin
N := length(Tables);
if N>SizeOf(SUPERVISOR_ACCESS_RIGHTS.Get)*8 then // TSQLAccessRights bits size
raise EModelException.CreateUTF8('% for "%" has too many Tables: %>%',
raise EModelException.CreateUTF8('% % has too many Tables: %>%',
[self,aRoot,N,SizeOf(SUPERVISOR_ACCESS_RIGHTS.Get)*8]); // e.g. N>64
// set the Tables to be associated with this Model, as TSQLRecord classes
fTablesMax := N-1;
if self=nil then
raise EModelException.Create('nil.GetTableIndexExisting');
if aTable=nil then
raise EModelException.CreateUTF8('aTable=nil for % "%"',[self,Root]);
raise EModelException.CreateUTF8('%.GetTableIndexExisting(nil) %',[self,Root]);
result := GetTableIndex(aTable);
if result<0 then
raise EModelException.CreateUTF8('% should be part of the % "%"',
[aTable,self,Root]);
raise EModelException.CreateUTF8('% is not part of % %',[aTable,self,Root]);
end;

function TSQLModel.GetTableExactIndex(const TableName: RawUTF8): integer;
if (aResponse<>'') and (sllServiceReturn in fLogFamily.Level) then
if IsHTMLContentTypeTextual(pointer(header)) then
log.Log(sllServiceReturn,aResponse,self,MAX_SIZE_RESPONSE_LOG) else
log.Log(sllServiceReturn,'% bytes "%"',[length(aResponse),header],self);
log.Log(sllServiceReturn,'% bytes [%]',[length(aResponse),header],self);
{$endif}
end;
end;
if Assigned(fOnIdle) then begin
if fBackgroundThread=nil then
fBackgroundThread := TSynBackgroundThreadEvent.Create(OnBackgroundProcess,
OnIdle,FormatUTF8('% "%" background',[Self,Model.Root]));
OnIdle,FormatUTF8('% % background',[Self,Model.Root]));
if not fBackgroundThread.RunAndWait(@Call) then
Call.OutStatus := HTTP_UNAVAILABLE;
end else
{$endif}
amBackgroundThread,amBackgroundORMSharedThread: begin
if Thread=nil then
Thread := Server.NewBackgroundThreadMethod('% "%" %',
Thread := Server.NewBackgroundThreadMethod('% % %',
[self,Server.Model.Root,ToText(Command)^]);
BackgroundExecuteThreadMethod(Method,Thread);
end;
GetInputByName(ParamName,'Int',v);
result := GetInt64(pointer(v),err);
if err<>0 then
raise EParsingException.CreateUTF8('%.InputInt[%]: "%" is not an integer',
raise EParsingException.CreateUTF8('%.InputInt[%]: ''%'' is not an integer',
[self,ParamName,v]);
end;

GetInputByName(ParamName,'Double',v);
result := GetExtended(pointer(v),err);
if err<>0 then
raise EParsingException.CreateUTF8('%.InputDouble[%]: "%" is not a float',
raise EParsingException.CreateUTF8('%.InputDouble[%]: ''%'' is not a float',
[self,ParamName,v]);
end;


procedure TSQLRestServer.SessionCreate(var User: TSQLAuthUser;
Ctxt: TSQLRestServerURIContext; out Session: TAuthSession);
var i: integer;
var i: PtrInt;
begin
Session := nil;
if (reOneSessionPerUser in Ctxt.Call^.RestAccessRights^.AllowRemoteExecute) and
if TAuthSession(fSessions.List[i]).User.fID=User.fID then begin
{$ifdef WITHLOG}
with TAuthSession(fSessions.List[i]) do
Ctxt.Log.Log(sllUserAuth,'User.LogonName=% already connected from "%/%"',
Ctxt.Log.Log(sllUserAuth,'User.LogonName=% already connected from %/%',
[User.LogonName,RemoteIP,Ctxt.Call^.LowLevelConnectionID],self);
{$endif}
Ctxt.AuthenticationFailed(afSessionAlreadyStartedForThisUser);
if OnSessionCreate(self,Session,Ctxt) then begin // TRUE aborts session creation
{$ifdef WITHLOG}
Ctxt.Log.Log(sllUserAuth,'Session aborted by OnSessionCreate() callback '+
'for User.LogonName=% (connected from "%/%") - clients=%, sessions=%',
'for User.LogonName=% (connected from %/%) - clients=%, sessions=%',
[User.LogonName,Session.RemoteIP,Ctxt.Call^.LowLevelConnectionID,
fStats.GetClientsCurrent,fSessions.Count],self);
{$endif}
'%.EngineBatchSend: DELETE not allowed on %',[self,RunTable]);
if not RecordCanBeUpdated(RunTable,ID,seDelete,@ErrMsg) then
raise EORMBatchException.CreateUTF8(
'%.EngineBatchSend: DELETE impossible: "%"',[self,ErrMsg]);
'%.EngineBatchSend: DELETE impossible [%]',[self,ErrMsg]);
end;
3: begin
// '{"Table":[...,"SIMPLE",[values],...]}' or '[...,"SIMPLE@Table",[values],...]'
'%.EngineBatchSend: SIMPLE/Add impossible: %',[self,ErrMsg]);
end;
else raise EORMBatchException.CreateUTF8(
'%.EngineBatchSend: Unknown "%" method',[self,Method]);
'%.EngineBatchSend: Unknown [%] method',[self,Method]);
end;
if (Count=0) and (EndOfObject=']') then begin
// single operation do not need a transaction nor InternalBatchStart/Stop
hash := fUniqueFields.List[i];
ndx := hash.Scan(Rec,fValue.Count); // O(n) search to avoid hashing
if ndx>=0 then begin
InternalLog('AddOne: Duplicated field "%" value for % and %',
InternalLog('AddOne: Duplicated field [%] value for % and %',
[hash.Field.Name,Rec,TSQLRecord(fValue.List[ndx])]);
result := 0; // duplicate unique fields -> error
exit;
if (fUniqueFields<>nil) and not NoUniqueFieldCheckOnAdd then
for i := 0 to fUniqueFields.Count-1 do // perform hash of List[Count-1]
if not TListFieldHash(fUniqueFields.List[i]).EnsureJustAddedNotDuplicated then begin
InternalLog('AddOne: Duplicated field "%" value for %',
InternalLog('AddOne: Duplicated field [%] value for %',
[TListFieldHash(fUniqueFields.List[i]).Field.Name,Rec]);
result := 0; // duplicate unique fields -> error
fValue.List[ndx] := nil; // avoid GPF within Delete()
fRemoteIP := aCtxt.RemoteIP;
{$ifdef WITHLOG}
aCtxt.Log.Log(sllUserAuth,
'New "%" session %/% created at %/% running %',
'New [%] session %/% created at %/% running %',
[User.GroupRights.Ident,User.LogonName,fIDCardinal,fRemoteIP,
aCtxt.Call^.LowLevelConnectionID,aCtxt.GetUserAgent],self);
{$endif}
if (arg>0) and not IdemPropName(method^.Args[arg].ParamName^,Val,ValLen) then begin
arg := method^.ArgIndex(Val,ValLen,false); // only if were not in-order
if arg<0 then
RaiseError('unexpected parameter "%"',[Val]);
RaiseError('unexpected parameter [%]',[Val]);
end;
end;
with method^.Args[arg] do begin
procedure RaiseError(const Args: array of const);
begin
raise EInterfaceFactoryException.CreateUTF8(
'%.Create: %.% "%" parameter has unexpected type %%',Args);
'%.Create: %.% [%] parameter has unexpected type %%',Args);
end;
begin
if aInterface=nil then
for a := ArgsOutFirst to ArgsOutLast do
if Args[a].ValueDirection in [smdVar,smdOut] then
raise EInterfaceFactoryException.CreateUTF8('%.Create: I% '+
'var/out parameter "%" not allowed with TServiceCustomAnswer result',
'var/out parameter [%] not allowed with TServiceCustomAnswer result',
[self,InterfaceDotMethodName,Args[a].ParamName^]);
ArgsResultIsServiceCustomAnswer := true;
end;
if cardinal(ndx)>=cardinal(fMethod^.ArgsInputValuesCount) then
break;
end;
raise EInterfaceStub.Create(fSender,fMethod^,'unknown input parameter "%"',[aParamName]);
raise EInterfaceStub.Create(fSender,fMethod^,'unknown input parameter [%]',[aParamName]);
end;

function TOnInterfaceStubExecuteParamsVariant.GetInUTF8(const ParamName: RawUTF8): RawUTF8;
if cardinal(ndx)>=cardinal(fMethod^.ArgsOutputValuesCount) then
break;
end;
raise EInterfaceStub.Create(fSender,fMethod^,'unknown output parameter "%"',[aParamName]);
raise EInterfaceStub.Create(fSender,fMethod^,'unknown output parameter [%]',[aParamName]);
end;

procedure TOnInterfaceStubExecuteParamsVariant.SetResultFromOutput;
if fInterfaceURI[1] in ['I','i'] then
delete(fInterfaceURI,1,1);
if fRest.Model.GetTableIndex(fInterfaceURI)>=0 then
raise EServiceException.CreateUTF8('%.Create: "%" interface name '+
'is already used by a SQL table name',[self,fInterfaceURI]);
raise EServiceException.CreateUTF8('%.Create: I% routing name is '+
'already used by a % SQL table name',[self,fInterfaceURI,fInterfaceURI]);
SetLength(fExecution,fInterface.fMethodsCount);
// compute interface signature (aka "contract"), serialized as a JSON object
FormatUTF8('{"contract":"%","implementation":"%","methods":%}',
i := ArgIndex(pointer(arg),length(arg),Input);
if i<0 then
if RaiseExceptionOnUnknownParam then
raise EServiceException.CreateUTF8('Unexpected "%" parameter for %',
raise EServiceException.CreateUTF8('Unexpected [%] parameter for %',
[arg,InterfaceDotMethodName]) else
ok := false;
arginfo := @Args[i];
@@ -800,10 +800,10 @@ constructor TSQLRestStorageExternal.Create(aClass: TSQLRecordClass;
if rpmQuoteFieldName in options then
fStoredClassMapping^.MapField(nfo.Name,'"'+SQL+'"') else
if fProperties.IsSQLKeyword(SQL) then begin
log.Log(sllWarning,'%.%: Field name "%" is not compatible with %',
log.Log(sllWarning,'%.%: Field name % is not compatible with %',
[fStoredClass,nfo.Name,SQL,fProperties.DBMSEngineName],self);
if rpmAutoMapKeywordFields in options then begin
log.Log(sllWarning,'-> %.% mapped to "%_"',[fStoredClass,nfo.Name,SQL],self);
log.Log(sllWarning,'-> %.% mapped to %_',[fStoredClass,nfo.Name,SQL],self);
fStoredClassMapping^.MapField(nfo.Name,SQL+'_');
end else
log.Log(sllWarning,'-> you should better use MapAutoKeywordFields',self);
@@ -918,7 +918,7 @@ function TSQLRestStorageExternal.AdaptSQLForEngineList(var SQL: RawUTF8): boolea
limit.Position := posNone else begin
limit := fProperties.SQLLimitClause(Stmt);
if limit.Position=posNone then begin
InternalLog('%.AdaptSQLForEngineList: unknown "%" LIMIT syntax for [%]',
InternalLog('%.AdaptSQLForEngineList: unknown % LIMIT syntax for [%]',
[ClassType,ToText(fProperties.DBMS)^,SQL],sllWarning);
exit;
end;
@@ -1924,7 +1924,7 @@ function TSQLRestStorageExternal.JSONDecodedPrepareToSQL(
k := fFieldsInternalToExternal[k+1]; // retrieve exact Types[f] from SynDB
if k<0 then
raise ESQLDBException.CreateUTF8(
'%.JSONDecodedPrepareToSQL(%): No column for "%" field in table %',
'%.JSONDecodedPrepareToSQL(%): No column for [%] field in table %',
[self,StoredClass,Decoder.FieldNames[f],fTableName]);
Types[f] := fFieldsExternal[k].ColumnType;
end;
@@ -1988,7 +1988,7 @@ function TSQLRestStorageExternal.ComputeSQL(
result := result+' desc';
end;
{$ifdef SQLVIRTUALLOGS}
SQLite3Log.Add.Log(sllDebug,'%.ComputeSQL "%" %',[ClassType,result,log],self);
SQLite3Log.Add.Log(sllDebug,'%.ComputeSQL [%] %',[ClassType,result,log],self);
{$endif}
end;

@@ -1175,7 +1175,7 @@ procedure TMVCViewsMustache.Render(methodIndex: Integer; const Context: variant;
Mustache := nil; // force reload ASAP
Locker.Leave;
raise EMVCException.CreateUTF8(
'%.Render(''%''): Void "%" Template - please put some content!',
'%.Render(''%''): Void [%] Template - please write some content!',
[self,ShortFileName,FileName]);
end;
end;
@@ -596,7 +596,7 @@ function TSQLRestStorageMongoDB.DocFromJSON(const JSON: RawUTF8;
ndx := fStoredClassRecordProps.Fields.IndexByName(doc.Names[i]);
if ndx<0 then
raise EORMMongoDBException.CreateUTF8(
'%.DocFromJSON: unkwnown field name "%"',[self,doc.Names[i]]);
'%.DocFromJSON: unkwnown field name [%]',[self,doc.Names[i]]);
doc.Names[i] := fStoredClassMapping^.ExtFieldNames[ndx];
info := fStoredClassRecordProps.Fields.List[ndx];
V := @doc.Values[i];
@@ -917,7 +917,7 @@ procedure TSQLRestStorageMongoDB.JSONFromDoc(var doc: TDocVariantData;
name := fStoredClassMapping^.ExternalToInternalOrNull(doc.Names[i]);
if name='' then
raise EORMMongoDBException.CreateUTF8(
'%.JSONFromDoc: Unknown field "%" for %',[self,doc.Names[i],fStoredClass]);
'%.JSONFromDoc: Unknown field [%] for %',[self,doc.Names[i],fStoredClass]);
W.AddFieldName(pointer(name),Length(name));
W.AddVariant(doc.Values[i],twJSONEscape);
W.Add(',');
@@ -987,7 +987,7 @@ function TSQLRestStorageMongoDB.RetrieveBlobFields(
if docv^.GetVarData(fBSONProjectionBlobFieldsNames[f],blob) then
BSONVariantType.ToBlob(variant(blob),blobRaw) else
raise EORMMongoDBException.CreateUTF8(
'%.RetrieveBlobFields(%): field "%" not found',
'%.RetrieveBlobFields(%): field [%] not found',
[self,Value,fBSONProjectionBlobFieldsNames[f]]);
(fStoredClassRecordProps.BlobFields[f] as TSQLPropInfoRTTIRawBlob).
SetBlob(Value,blobRaw);
@@ -1117,7 +1117,7 @@ procedure AddWhereClause(B: TBSONWriter);
with Stmt.Where[w] do begin
FieldName := fStoredClassMapping^.FieldNameByIndex(Field-1)+SubField;
if not B.BSONWriteQueryOperator(FieldName,NotClause,Operator,ValueVariant) then begin
InternalLog('%.EngineList: operator % not supported for field "%" in [%]',
InternalLog('%.EngineList: operator % not supported for field [%] in [%]',
[ClassType,ToText(Operator)^,FieldName,SQL],sllError);
exit;
end;

0 comments on commit f3e777d

Please sign in to comment.
You can’t perform that action at this time.