Miva Empresa/Mia/Script Compiler v5.32 Release Notes ---------------------------------------------------- Bugs Fixed ---------- 23788: OpenSSL thread locking callback is called after all threads have been joined and cleanup has begun 24758: CompilerParser::Find_ScratchVariable_Ident can be susceptible to a buffer overflow 24759: Passing a negative value for the "-O" flag causes a segfault 24762: mvc fails to pass the verbose flag to the assembler 24817: The JSONDecoder should clear any existing data from the output parameter 26511: LOWER function leaks memory 26512: UPPER function leaks memory 26517: SQL_Stack::PopBool should use the string length, not the string size 26518: MivaSQL crashes when search condition does not contain RHS operators 26522: MivaSQL UNION should remove duplicates from individual result sets 26525: SQL_Bucket_Record does not delete the value popped off of the stack 26556: MvSMTP should clear the g.MvSMTP_Error variable on a successful connection 26572: PostgreSQL: Add prepared statement to cache after query is executed / view is closed 26602: Compiler: MvOPENVIEW should output a compiler error if the QUERY attribute is missing 26767: CommandLine_Warning_Flags has bad index boundary checks 26772: LocateDSOs should output an error when the .so/.DLL directory encounters an error 26841: UNIXReentrantFileManager::DirectoryListing should use readdir_r 26881: Generate SHA256SUMS of all distribution files and components 27000: VariableHash::LookupVariable_Fancy on present but uncreated variable causes a crash 27031: DefaultDatabaseVariable::Clone is cloning the wrong variable 27037: SpecialVariables values are not set to the parent's value in a multi-threaded environment New Builtin Functions --------------------- - file_set_time( path, location, modified ) Sets the file's modified time Parameters: - path - The path to the file - location - Either script or data - modified - time_t (seconds since 1-JAN-1970) Return Value: - 1 on success, 0 on failure - crypto_next_error() Gets the next crypto error Parameters: - None Return Value: - The appropriate crypto error - crypto_clear_error() Will clear out all crypto errors Parameters: - None Return Value: - Empty - crypto_evp_sign( digestname, privkey, buffer, signature var ) Generates an RSA / ECDSA signature Parameters: - digestname - Hash algorithm name, such as "md5" or "sha256". Supported digest algorithms will vary between OpenSSL installations - privkey - EVP PKEY structure reference - buffer - The data to sign - signature - The signed output signature Return Value: - 1 on success, 0 on failure - crypto_evp_verify( digestname, pubkey, buffer, signature ) Verifies an RSA / ECDSA signature Parameters: - digestname - Hash algorithm name, such as "md5" or "sha256". Supported digest algorithms will vary between OpenSSL installations - pubkey - EVP PKEY structure reference - buffer - The data to verify - signature - The signature to verify Return Value: - 1 on success, 0 on failure - evp_pkey_load_pubkey_x509( x509 var, pkey var ) Loads a PKEY reference from an x509 public key reference Parameters: - x509 - Certificate reference returned from functions such as x509_load_mem - pkey - Structure reference Return Value: - 1 on success, 0 on failure Other ----- - crypto_last_error Previously if the crypto error originated from Miva Empresa, the returned error was always the same. If the crypto error was from OpenSSL then it would be lost after calling the function. Modified to always return the last crypto error. - trim / ltrim / rtrim Will now trim whitespace from arrays and structures. Previously the functions would convert arrays and structures to serialized data and then trim it. Arrays and structures are now iterated and all values within are trimmed appropriately. - POST content type of "application/json" is now supported. The POSTed data will be parsed and stored in the s.json_data variable as a JSON object. The raw POSTed data will populate the s.content_data variable. - Added the FLAGS attribute to MvCALL / mvt:call. The only supported flag currently is "noparse" which will disable parsing of the returned data. The data will populate the s.callvalue variable. This is ideal if you do not need to iterate HTML / XML elements. - evp_pkey_load_mem now supports the DER and PEM formats. - Added support for Redis. The use of the redis functions can be obtained by adding a system library with the code of "hiredis." - The compiler now warns when text / HTML is present and will not be output in the current context. Configuration Changes --------------------- - Added the following configuration options: MvCONFIG_ERROR_SYSLOG_IDENT: - Only available on Win32. - IIS7 - Set the ident value under the syslog configuration section - Mia - Set the errorsyslogident registry key MvCONFIG_ERROR_SYSLOG - IIS7 - Set the syslog value under the syslog configuration section - Mia - Set the errorsyslog registry key - 3x - Set the errorsyslog directive in mivavm.conf - env - Set the environment variable MvCONFIG_ERROR_SYSLOG MvCONFIG_ERROR_SYSLOG_FACILITY - Only available on UNIX systems. - 3x - Set the errorsyslogfacility directive in mivavm.conf - env - Set the environment variable MvCONFIG_ERROR_SYSLOG_PRIORITY MvCONFIG_ERROR_SYSLOG_PRIORITY - Only available on UNIX systems. - 3x - Set the errorsyslogpriority directive in mivavm.conf - env - Set the environment variable MvCONFIG_ERROR_SYSLOG_PRIORITY MvCONFIG_ERROR_SYSLOG - A comma separated list of different types of Miva Empresa errors that should be logged to the system log. E.g. fatal,timeout,MvDO,MvCALL:"Unable to open URL" The "fatal" directive will cause all fatal errors to be logged The "timeout" directive will cause all timeout errors to be logged The will cause all those specific tag errors to be logged. - In addition, you may specify a quoted string after each directive which specifies a "contains" string that must be present in the associated error message in order to be logged. For example, you could specify "MvCALL:"Unable to open URL"." If the MvCALL errors, the error will only be logged if the error message contains "Unable to open URL." MvCONFIG_ERROR_SYSLOG_IDENT - Sets the identifier for the data being written to the Application Event Log. Defaults to "Miva." MvCONFIG_ERROR_SYSLOG_FACILITY - String representation of the facility passed to openlog. E.g. "local2", "cron", "mail", etc... Defaults to "local2." MvCONFIG_ERROR_SYSLOG_PRIORITY - String representation of the option passed to openlog. E.g. "alert", "debug", etc... Defaults to "err" Redis ----- - redis_connect( ip, port, conn_id var ) Connects to Redis on the specified IP / hostname and port. Parameters: - ip / hostname: The IP address / hostname of the server Redis is on - port: The port number to connect on - conn_id: An output value containing an reference ID which is associated to the internal Redis connection Return Value: - 1 on success, 0 on failure - redis_disconnect( conn_id ) Disconnects the specified instance from the Redis server Parameters: - conn_id: The internal reference ID Return Value: - 1 on success, 0 on failure - redis_last_error() Gets the last error message Parameters: - None Return Value: - The last error message The following are implementations of Redis functions. All functions take a Redis connection reference and work as described by redis.io. - redis_auth( conn_id, password ) - https://redis.io/commands/auth - redis_echo( conn_id, message ) - https://redis.io/commands/echo - redis_ping( conn_id ) - https://redis.io/commands/ping - redis_ping_message( conn_id, message ) - https://redis.io/commands/ping - redis_quit( conn_id ) - https://redis.io/commands/quit - redis_select( conn_id, index ) - https://redis.io/commands/select - redis_geoadd( conn_id, key, longitude, latitude, member ) - https://redis.io/commands/geoadd - redis_geodist( conn_id, key, member1, member2, options var ) - https://redis.io/commands/geodist - redis_geohash( conn_id, key, member, output var ) - https://redis.io/commands/geohash - redis_geopos( conn_id, key, member, output var ) - https://redis.io/commands/geopos - redis_georadius( conn_id, key, longitude, latitude, radius, unit, options var, output var ) - https://redis.io/commands/georadius - redis_georadiusstore( conn_id, key, longitude, latitude, radius, unit, store_key, count ) - https://redis.io/commands/georadius - redis_georadiusstoredist( conn_id, key, longitude, latitude, radius, unit, storedist_key, count ) - https://redis.io/commands/georadius - redis_georadiusbymember( conn_id, key, member, radius, unit, options var, output var ) - https://redis.io/commands/georadiusbymember - redis_georadiusbymemberstore( conn_id, key, member, latitude, radius, unit, store_key ) - https://redis.io/commands/georadiusbymember - redis_georadiusbymemberstoredist( conn_id, key, member, latitude, radius, unit, storedist_key ) - https://redis.io/commands/georadiusbymember - redis_hdel( conn_id, key, field ) - https://redis.io/commands/hdel - redis_hexists( conn_id, key, field ) - https://redis.io/commands/hexists - redis_hget( conn_id, key, field ) - https://redis.io/commands/hget - redis_hgetall( conn_id, key, output var ) - https://redis.io/commands/hgetall - redis_hincrby( conn_id, key, field, increment ) - https://redis.io/commands/hincrby - redis_hincrbyfloat( conn_id, key, field, increment ) - https://redis.io/commands/hincrbyfloat - redis_hkeys( conn_id, key, output var ) - https://redis.io/commands/hkeys - redis_hlen( conn_id, key ) - https://redis.io/commands/hlen - redis_hmget( conn_id, key, field, output var ) - https://redis.io/commands/hmget - redis_hmset( conn_id, key, field, value ) - https://redis.io/commands/hmset - redis_hscan( conn_id, key, cursor, options var, output var ) - https://redis.io/commands/hscan - redis_hset( conn_id, key, field, value ) - https://redis.io/commands/hset - redis_hsetnx( conn_id, key, field, value ) - https://redis.io/commands/hsetnx - redis_hstrlen( conn_id, key, field ) - https://redis.io/commands/hstrlen - redis_hvals( conn_id, key, output var ) - https://redis.io/commands/hvals - redis_pfadd( conn_id, key, element ) - https://redis.io/commands/pfadd - redis_pfcount( conn_id, key ) - https://redis.io/commands/pfcount - redis_pfmerge( conn_id, destkey, sourcekey ) - https://redis.io/commands/pfmerge - redis_del( conn_id, key ) - https://redis.io/commands/del - redis_dump( conn_id, key ) - https://redis.io/commands/dump - redis_exists( conn_id, key ) - https://redis.io/commands/exists - redis_expire( conn_id, key, seconds ) - https://redis.io/commands/expire - redis_expireat( conn_id, key, timestamp ) - https://redis.io/commands/expireat - redis_keys( conn_id, pattern, output var ) - https://redis.io/commands/keys - redis_migrate( conn_id, host, port, key, destination_db, timeout, options var ) - https://redis.io/commands/migrate - redis_move( conn_id, key, db ) - https://redis.io/commands/move - redis_object_encoding( conn_id, key ) - https://redis.io/commands/object - redis_object_idletime( conn_id, key ) - https://redis.io/commands/object - redis_object_refcount( conn_id, key ) - https://redis.io/commands/object - redis_persist( conn_id, key ) - https://redis.io/commands/persist - redis_pexpire( conn_id, key, milliseconds ) - https://redis.io/commands/pexpire - redis_pexpireat( conn_id, key, milliseconds_timestamp ) - https://redis.io/commands/pexpireat - redis_pttl( conn_id, key ) - https://redis.io/commands/pttl - redis_randomkey( conn_id ) - https://redis.io/commands/randomkey - redis_rename( conn_id, key, newkey ) - https://redis.io/commands/rename - redis_renamenx( conn_id, key, newkey ) - https://redis.io/commands/renamenx - redis_restore( conn_id, key, ttl, serialized_value, options var ) - https://redis.io/commands/restore - redis_scan( conn_id, cursor, options var, output var ) - https://redis.io/commands/scan - redis_sort( conn_id, key, options var, output var ) - https://redis.io/commands/sort - redis_sortstore( conn_id, key, destination, options var ) - https://redis.io/commands/sort - redis_touch( conn_id, key ) - https://redis.io/commands/touch - redis_ttl( conn_id, key ) - https://redis.io/commands/ttl - redis_type( conn_id, key ) - https://redis.io/commands/type - redis_blpop( conn_id, key, timeout, output var ) - https://redis.io/commands/blpop - redis_brpop( conn_id, key, timeout, output var ) - https://redis.io/commands/brpop - redis_brpoplpush( conn_id, source, destination, timeout ) - https://redis.io/commands/brpoplpush - redis_lindex( conn_id, key, index ) - https://redis.io/commands/lindex - redis_linsert_before( conn_id, key, pivot, value ) - https://redis.io/commands/linsert - redis_linsert_after( conn_id, key, pivot, value ) - https://redis.io/commands/linsert - redis_llen( conn_id, key ) - https://redis.io/commands/llen - redis_lpop( conn_id, key ) - https://redis.io/commands/lpop - redis_lpush( conn_id, key, value ) - https://redis.io/commands/lpush - redis_lpushx( conn_id, key, value ) - https://redis.io/commands/lpushx - redis_lrange( conn_id, key, start, stop, output var ) - https://redis.io/commands/lrange - redis_lrem( conn_id, key, count, value ) - https://redis.io/commands/lrem - redis_lset( conn_id, key, index, value ) - https://redis.io/commands/lset - redis_ltrim( conn_id, key, start, stop ) - https://redis.io/commands/ltrim - redis_rpop( conn_id, key ) - https://redis.io/commands/rpop - redis_rpoplpush( conn_id, source, destination ) - https://redis.io/commands/rpoplpush - redis_rpush( conn_id, key, value ) - https://redis.io/commands/rpush - redis_rpushx( conn_id, key, value ) - https://redis.io/commands/rpushx - redis_eval( conn_id, script, key, arg ) - https://redis.io/commands/eval - redis_eval_array( conn_id, script, key, arg, output var ) - https://redis.io/commands/eval - redis_evalsha( conn_id, sha1, key, arg ) - https://redis.io/commands/evalsha - redis_evalsha_array( conn_id, sha1, key, arg, output var ) - https://redis.io/commands/evalsha - redis_script_exists( conn_id, sha1, output var ) - https://redis.io/commands/script-exists - redis_script_flush( conn_id ) - https://redis.io/commands/script-flush - redis_script_kill( conn_id ) - https://redis.io/commands/script-kill - redis_script_load( conn_id, script ) - https://redis.io/commands/script-load - redis_bgsave( conn_id ) - https://redis.io/commands/bgsave - redis_client_getname( conn_id ) - https://redis.io/commands/client-getname - redis_client_kill( conn_id, options var ) - https://redis.io/commands/client-kill - redis_client_list( conn_id ) - https://redis.io/commands/client-list - redis_client_pause( conn_id, timeout ) - https://redis.io/commands/client-pause - redis_client_setname( conn_id, name ) - https://redis.io/commands/client-setname - redis_command( conn_id, output var ) - https://redis.io/commands/command - redis_command_count( conn_id ) - https://redis.io/commands/command - redis_command_getkeys( conn_id, input var, output var ) - https://redis.io/commands/command - redis_command_info( conn_id, command_name, output var ) - https://redis.io/commands/command - redis_config_get( conn_id, parameter, output var ) - https://redis.io/commands/config-get - redis_config_resetstat( conn_id ) - https://redis.io/commands/config-resetstat - redis_config_rewrite( conn_id ) - https://redis.io/commands/config-rewrite - redis_config_set( conn_id, parameter, value ) - https://redis.io/commands/config-set - redis_dbsize( conn_id ) - https://redis.io/commands/dbsize - redis_debug_object( conn_id, key ) - https://redis.io/commands/debug-object - redis_debug_segfault( conn_id ) - https://redis.io/commands/debug-segfault - redis_flushall( conn_id ) - https://redis.io/commands/flushall - redis_flushdb( conn_id ) - https://redis.io/commands/flushdb - redis_info( conn_id ) - https://redis.io/commands/info - redis_info_section( conn_id, section ) - https://redis.io/commands/info - redis_lastsave( conn_id ) - https://redis.io/commands/lastsave - redis_role( conn_id, output var ) - https://redis.io/commands/role - redis_save( conn_id ) - https://redis.io/commands/save - redis_shutdown( conn_id ) - https://redis.io/commands/shutdown - redis_shutdown_nosave( conn_id ) - https://redis.io/commands/shutdown - redis_shutdown_save( conn_id ) - https://redis.io/commands/shutdown - redis_slowlog_get( conn_id, output var ) - https://redis.io/commands/slowlog - redis_slowlog_get_count( conn_id, count, output var ) - https://redis.io/commands/slowlog - redis_slowlog_len( conn_id ) - https://redis.io/commands/slowlog - redis_slowlog_reset( conn_id ) - https://redis.io/commands/slowlog - redis_time( conn_id, output var ) - https://redis.io/commands/time - redis_sadd( conn_id, key, member ) - https://redis.io/commands/sadd - redis_scard( conn_id, key ) - https://redis.io/commands/scard - redis_sdiff( conn_id, key, output var ) - https://redis.io/commands/sdiff - redis_sdiffstore( conn_id, destination, key ) - https://redis.io/commands/sdiff - redis_sinter( conn_id, key, output var ) - https://redis.io/commands/sinter - redis_sinterstore( conn_id, destination, key ) - https://redis.io/commands/sinter - redis_sismember( conn_id, key, member ) - https://redis.io/commands/sismember - redis_smembers( conn_id, key, output var ) - https://redis.io/commands/smembers - redis_smove( conn_id, source, destination, member ) - https://redis.io/commands/smove - redis_spop( conn_id, key ) - https://redis.io/commands/spop - redis_spop_count( conn_id, key, count, output var ) - https://redis.io/commands/spop - redis_srandmember( conn_id, key ) - https://redis.io/commands/srandmember - redis_srandmember_count( conn_id, key, count, output var ) - https://redis.io/commands/srandmember - redis_srem( conn_id, key, member ) - https://redis.io/commands/srem - redis_sscan( conn_id, key, cursor, options var, output var ) - https://redis.io/commands/sscan - redis_sunion( conn_id, key, output var ) - https://redis.io/commands/sunion - redis_sunionstore( conn_id, destination, key ) - https://redis.io/commands/sunion - redis_zadd( conn_id, key, score, member, options var ) - https://redis.io/commands/zadd - redis_zcard( conn_id, key ) - https://redis.io/commands/zcard - redis_zcount( conn_id, key, min, max ) - https://redis.io/commands/zcount - redis_zincrby( conn_id, key, increment, member ) - https://redis.io/commands/zincrby - redis_zinterstore( conn_id, destination, key, options var ) - https://redis.io/commands/zinterstore - redis_zlexcount( conn_id, key, min, max ) - https://redis.io/commands/zlexcount - redis_zrange( conn_id, key, start, stop, options var, output var ) - https://redis.io/commands/zrange - redis_zrangebylex( conn_id, key, min, max, options var, output var ) - https://redis.io/commands/zrangebylex - redis_zrangebyscore( conn_id, key, min, max, options var, output var ) - https://redis.io/commands/zrangebyscore - redis_zrank( conn_id, key, member ) - https://redis.io/commands/zrank - redis_zrem( conn_id, key, member ) - https://redis.io/commands/zrem - redis_zremrangebylex( conn_id, key, min, max ) - https://redis.io/commands/zremrangebylex - redis_zremrangebyrank( conn_id, key, start, stop ) - https://redis.io/commands/zremrangebyrank - redis_zremrangebyscore( conn_id, key, min, max ) - https://redis.io/commands/zremrangebyscore - redis_zrevrange( conn_id, key, start, stop, options var, output var ) - https://redis.io/commands/zrevrange - redis_zrevrangebylex( conn_id, key, max, min, options var, output var ) - https://redis.io/commands/zrevrangebylex - redis_zrevrangebyscore( conn_id, key, max, min, optoins var, output var ) - https://redis.io/commands/zrevrangebyscore - redis_zrevrank( conn_id, key, member ) - https://redis.io/commands/zrevrank - redis_zscan( conn_id, key, cursor, options var, output var ) - https://redis.io/commands/zscan - redis_zscore( conn_id, key, member ) - https://redis.io/commands/zscore - redis_zunionstore( conn_id, destination, key, options var ) - https://redis.io/commands/zunionstore - redis_append( conn_id, key, value ) - https://redis.io/commands/append - redis_bitcount( conn_id, key, options var ) - https://redis.io/commands/bitcount - redis_bitfield( conn_id, key, options var, output var ) - https://redis.io/commands/bitfield - redis_bitop( conn_id, operation, destkey, key ) - https://redis.io/commands/bitop - redis_bitpos( conn_id, key, bit, options var ) - https://redis.io/commands/bitpos - redis_decr( conn_id, key ) - https://redis.io/commands/decr - redis_decrby( conn_id, key, decrement ) - https://redis.io/commands/decrby - redis_get( conn_id, key ) - https://redis.io/commands/get - redis_getbit( conn_id, key, offset ) - https://redis.io/commands/getbit - redis_getrange( conn_id, key, start, end ) - https://redis.io/commands/getrange - redis_getset( conn_id, key, value ) - https://redis.io/commands/getset - redis_incr( conn_id, key ) - https://redis.io/commands/incr - redis_incrby( conn_id, key, increment ) - https://redis.io/commands/incrby - redis_incrbyfloat( conn_id, key, increment ) - https://redis.io/commands/incrbyfloat - redis_mget( conn_id, key, output var ) - https://redis.io/commands/mget - redis_mset( conn_id, key, value ) - https://redis.io/commands/mset - redis_msetnx( conn_id, key, value ) - https://redis.io/commands/msetnx - redis_set( conn_id, key, value, options var ) - https://redis.io/commands/set - redis_setbit( conn_id, key, offset, value ) - https://redis.io/commands/setbit - redis_setrange( conn_id, key, offset, value ) - https://redis.io/commands/setrange - redis_strlen( conn_id, key ) - https://redis.io/commands/strlen - redis_discard( conn_id ) - https://redis.io/commands/discard - redis_exec( conn_id, output var ) - https://redis.io/commands/exec - redis_multi( conn_id ) - https://redis.io/commands/multi - redis_unwatch( conn_id ) - https://redis.io/commands/unwatch - redis_watch( conn_id, key ) - https://redis.io/commands/watch