-
Content Count
125 -
Joined
-
Last visited
-
Days Won
2
Davide Angeli last won the day on February 14 2024
Davide Angeli had the most liked content!
Community Reputation
46 ExcellentAbout Davide Angeli
- Birthday 11/24/1971
Technical Information
-
Delphi-Version
Delphi 13 Florence
Recent Profile Visitors
-
ISuperObject decimal issue with currency values
Davide Angeli replied to Davide Angeli's topic in Delphi Third-Party
it seems to already be there... -
ISuperObject decimal issue with currency values
Davide Angeli replied to Davide Angeli's topic in Delphi Third-Party
It's not the same library but seems quite similar... -
ISuperObject decimal issue with currency values
Davide Angeli replied to Davide Angeli's topic in Delphi Third-Party
I'm using this one: https://github.com/onryldz/x-superobject, latest changes are 5 years ago... I don't see an O.C[] property in this one. Is there another version available somewhere? -
ISuperObject decimal issue with currency values
Davide Angeli replied to Davide Angeli's topic in Delphi Third-Party
I agree. Unfortunately, ISuperObject does not support the direct insertion of currency type data. -
ISuperObject decimal issue with currency values
Davide Angeli replied to Davide Angeli's topic in Delphi Third-Party
const FloatFormat : TFormatSettings = ( DecimalSeparator : '.' ); -
ISuperObject decimal issue with currency values
Davide Angeli replied to Davide Angeli's topic in Delphi Third-Party
procedure TJSONFloat.AsJSONString(Str: TJSONWriter); begin if FNull then Str.AppendVal( cNull ) else Str.AppendVal( FloatToStr(Value, FloatFormat) ); end; -
I have a problem that's driving me crazy. I'm using ISuperObject to store in a JSON string a series of complex (non-tabular) data in a Firebird memo field. Within this JSON, some numerical data with two decimal places (which are currency type variables in Delphi) is being stored. In a couple of cases (which I unfortunately can't replicate myself with the same values), some of my customers, upon saving this data, ended up with more than two decimal places in the resulting JSON (for example, 2332.89 became 2332.889xxxx). I'm using the ISuperObject property like this O.F['namevar']:=currencyvalue to insert the data into the JSON. Do you think it's possible that the behavior of ISuperObject might vary on certain computers, leading to the problem I've encountered?
-
Keybindings get unregistered in an unknown scenario
Davide Angeli replied to havrlisan's topic in MMX Code Explorer
I don't know if it's related, but I've also had problems with keyboard shortcuts ever since I upgraded to Delphi 12 (and now with Delphi 13 as well). The shortcuts that allow me to enter block selection mode no longer work for me. I opened a ticket for version 12, but it was ignored and problem persiste in 13 and for me is very annoying (https://embt.atlassian.net/servicedesk/customer/portal/1/RSS-611). Furthermore, the keyboard shortcut for 'toggle comment' occasionally stops working, and I can't figure out the dynamic behind it. Usually, the issue disappears after closing and reopening the IDE. -
I've written to the devoleper and it seems he is working on it. It should release an update this week. In general, however, I find it frustrating that component devolepers wait for the official release of the new Delphi to start working on updating their products. I can understand small developers, but there are some big-name suites that haven't made an update available yet (TMS, for example). Shouldn't the beta releases of the IDE also serve this purpose? Having the source code allows you to improvise a recompilation, but that's always time stolen from development, because you always have to make small adjustments to source code that isn't our own.
-
When this happens, checking the Windows Event Viewer can be useful: any unusual exceptions might be logged there.
-
SOAP service with WS-Security (WSS with X.509 certificates)
Davide Angeli replied to Davide Angeli's topic in Network, Cloud and Web
Hi, this is what is working for me. You'll probably need to adapt it because it is built based on my needs, but I hope it can be a good starting point for you. // Returns 0 = ok (sign and encrypt is fine) // 1 = failed open keystore to sign/encrypt // 2 = failed to load sing/encryption certificate function SBBSoapSignAndEncryptJKS(const InputFilename, OutputFilename, JKSFileName : String; OnPasswordNeeded : TPasswordNeededEvent; out Error : String; DebugSign : Boolean = FALSE) : Integer; var XMLEncryptor : TsbxXMLEncryptor; SOAPSigner : TsbxSOAPSigner; NSItem : TsbxXMLNamespace; sCSerialNumber,sIssuer : String; begin Result:=0; Error:=''; // calculate some IDs and variables for debug purpose var BinarySecurityTokenID:='X509-'+FormatDateTime('yyyymmddhhnnsszzz',Now); var BodyReference:='ID-'+FormatDateTime('yyyymmddhhnnsszzz',Now); var EncryptedDataID:='ED-'+FormatDateTime('yyyymmddhhnnsszzz',Now); var EncryptedKeyID:='EK-'+FormatDateTime('yyyymmddhhnnsszzz',Now); // some temporary variables to handle debug filenames var BasePath:=ExtractFilePath(OutputFileName); var BaseFileName:=ExtractFileName(InputFileName); BaseFileName:=BaseFileName.SubString(0,BaseFileName.IndexOf('.')); XMLEncryptor := TsbxXMLEncryptor.Create(nil); SOAPSigner := TsbxSOAPSigner.Create(nil); try /// Step 1 /// Signing body element var CertificateStorage := TsbxCertificateStorage.Create(Nil); try try CertificateStorage.OnPasswordNeeded:=OnPasswordNeeded; CertificateStorage.Open('java://'+JKSFileName); if CertificateStorage.Opened then begin CertificateStorage.Select('*',True,1); SOAPSigner.SigningCertificate:=CertificateStorage.SelectedCertificates[0]; end else begin Result:=1; Error:='Failed to open keystore to sign'; Exit; end; except on E: Exception do begin Result:=2; Error:='Failed to signing load certificate: ' + E.Message; Exit; end; end; finally FreeAndNil(CertificateStorage); end; SOAPSigner.InputFile := InputFilename; SOAPSigner.InputBytes := SOAPSigner.OutputBytes; SOAPSigner.NewSignature.SignatureType := sstWSSSignature; SOAPSigner.NewSignature.HashAlgorithm := 'SHA1'; SOAPSigner.NewSignature.XAdES := false; SOAPSigner.SecurityHeaderIndex := -1; var k := SOAPSigner.AddBodyReference(BodyReference, false); SOAPSigner.References[k].InclusiveNamespacesPrefixList := 'xsd xsi'; SOAPSigner.Config('KeyInfoID=KI-'+FormatDateTime('yyyymmddhhnnsszzz',Now)); SOAPSigner.Config('SecurityTokenReferenceID=STR-'+FormatDateTime('yyyymmddhhnnsszzz',Now)); SOAPSigner.Config('BinarySecurityTokenID='+BinarySecurityTokenID); SOAPSigner.Config('InclusiveNamespacesPrefixList=SOAP-ENV xsd xsi'); SOAPSigner.Config('PrependCustomXML=<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="TS-'+FormatDateTime('yyyymmddhhnnsszzz',Now)+'">' + '<wsu:Created>'+DateToISO8601(Now,False)+'</wsu:Created>' + '<wsu:Expires>'+DateToISO8601(IncMinute(Now,50),False)+'</wsu:Expires>' + '</wsu:Timestamp>'); SOAPSigner.Sign; // - just for debug purpose save the signed result if DebugSign then TFile.WriteAllBytes(BasePath+BaseFileName+'signed.xml', SOAPSigner.OutputBytes); /// Step 2 /// Encrypting body element CertificateStorage := TsbxCertificateStorage.Create(Nil); try try CertificateStorage.OnPasswordNeeded:=OnPasswordNeeded; CertificateStorage.Open('java://'+JKSFileName); if CertificateStorage.Opened then begin XMLEncryptor.KeyEncryptionCertificate:=CertificateStorage.Certificates[1]; sCSerialNumber:=TBytesSerialToInt64(XMLEncryptor.KeyEncryptionCertificate.SerialNumber).ToString; sIssuer:=XMLEncryptor.KeyEncryptionCertificate.IssuerRDN; var a:=sIssuer.Split(['/']); Delete(a,0,1); sIssuer:=''; for var J:=High(a) downto Low(a) do begin if Not sIssuer.IsEmpty then sIssuer:=sIssuer+','; sIssuer:=sIssuer+a[J]; end; end else begin Result:=1; Error:='Failed to open keystore to encrypt'; Exit; end; except on E: Exception do begin Result:=2; Error:='Failed to load encrypt certificate: ' + E.Message; Exit; end; end; finally FreeAndNil(CertificateStorage); end; XMLEncryptor.InputBytes := SOAPSigner.OutputBytes; XMLEncryptor.XMLNode := '/SOAP-ENV:Envelope/SOAP-ENV:Body'; XMLEncryptor.EncryptedDataType := cxedtContent; XMLEncryptor.EncryptionMethod := 'AES128'; XMLEncryptor.EncryptKey := true; XMLEncryptor.KeyEncryptionType := cxetKeyTransport; XMLEncryptor.KeyTransportMethod := cxktRSAOAEP; XMLEncryptor.Config('EncryptedKeyID='+EncryptedKeyID); XMLEncryptor.Config('EncryptedDataID='+EncryptedDataID); XMLEncryptor.Config('EncryptedKeyXMLElement=/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security'); XMLEncryptor.Config('KeyInfoCustomXML=<wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"'+ ' xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"' + ' xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">' + '<wsse:Reference URI="#'+EncryptedKeyID+'"/>' + '</wsse:SecurityTokenReference>'); XMLEncryptor.Config('EncryptedKeyInfoCustomXML=<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">' + '<ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">' + '<ds:X509IssuerSerial>' + '<ds:X509IssuerName>'{'CN='}+sIssuer+'</ds:X509IssuerName>' + '<ds:X509SerialNumber>'+sCSerialNumber+'</ds:X509SerialNumber>' + '</ds:X509IssuerSerial>' + '</ds:X509Data>' + '</wsse:SecurityTokenReference>'); XMLEncryptor.Encrypt; /// Step 3 SOAPSigner.InputBytes := XMLEncryptor.OutputBytes; SOAPSigner.InputFile := ''; SOAPSigner.OutputFile := OutputFilename; SOAPSigner.Open; // for XPath expressions we need to define prefixes used // prefixes: SOAP-ENV, xenc, wsu, ds - are already known by the component // wsse prefix better to define explicitly, since it is SOAP version specific NSItem := TsbxXMLNamespace.Create; try NSItem.Prefix := 'wsse'; NSItem.URI := 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'; SOAPSigner.XPathNamespaces.Add(NSItem); finally FreeAndNil(NSItem); end; SOAPSigner.SetInnerXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/xenc:EncryptedKey', SOAPSigner.GetInnerXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/xenc:EncryptedKey') + '<xenc:ReferenceList>' + '<xenc:DataReference URI="#'+EncryptedDataID+'"/>' + '</xenc:ReferenceList>'); SOAPSigner.SetInnerXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security', SOAPSigner.GetOuterXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/xenc:EncryptedKey') + SOAPSigner.GetOuterXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:BinarySecurityToken') + SOAPSigner.GetOuterXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsu:Timestamp') + SOAPSigner.GetOuterXML('/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/ds:Signature') ); SOAPSigner.Close(true); finally FreeAndNil(XMLEncryptor); FreeAndNil(SOAPSigner); end; end; -
IOUtils.pas vs. SysUtils.pas
Davide Angeli replied to chkaufmann's topic in RTL and Delphi Object Pascal
I think that initially the unit System.IOUtils.pas was created to provide platform-safe functions (windows, mac, android etc). Now I see many IFDEFs even in SysUtils... -
I've been using Delphi for at least 30 years, often for 9 hours a day. In my humble opinion, the IDE's instability can also be attributed to the way we work, regardless of the tools and components installed, which may or may not be stable. It's a fact that since version 10, my preferred way of working, which I use for my main project, has been causing the IDE to crash with a wide variety of errors (the most common being F2084 Internal Error). My project uses runtime packages that I created, several DLLs, an EXE, and the IDE also has a package installed with components that I developed, which shares the aforementioned runtime packages. For convenience and speed, everything was enclosed in a single project group. When I maintained my component library, to apply changes to the entire group, I always worked by doing a "compile all" of everything in the group: runtime packages, visual component package, DLLs, and then the EXE. In this context, if there are any forms open in the IDE, the IDE's instability is amplified to the nth degree, and the error is almost systematic. Since Embarcadero is unable to fix these errors (it's almost impossible to provide a test situation to open a report), I've had to adapt by changing my system, even though it's more cumbersome for me: I first compile the runtime and design packages, now placed in another project group, and then compile the application (DLL, EXE) by continuously switching between the two project groups. In this way, the IDE rarely crashes. The critical point in my case is certainly when the IDE needs to unload the design package from memory in order to compile it, and it's clearly not able to handle the unloading of any open forms that use the components present in the package being compiled. This is my experience. And by the way, the menu item that's clicked the most in the latest versions (including 12.2) is "Reload LSP Server" because it just doesn't want to work as it should.
-
To get that kind of info from a file I use the JCL class TJvVersionInfo (https://github.com/project-jedi/jvcl/blob/master/jvcl/run/JvVersionInfo.pas) that is a wrapper of that kind API. For me it works both 32 and 64 bit.
-
I'm using SecureBlackBox for other purpose (quite expensive tool!). In the suite (very rich) there is also an SFTP client: https://cdn.nsoftware.com/help/SBJ/dlp/SFTPClient.htm#SFTPClient