]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-5.6'
authorNikita Popov <nikic@php.net>
Tue, 2 Sep 2014 12:28:07 +0000 (14:28 +0200)
committerNikita Popov <nikic@php.net>
Tue, 2 Sep 2014 12:28:07 +0000 (14:28 +0200)
Conflicts:
ext/gmp/gmp.c

1  2 
ext/gmp/gmp.c

diff --cc ext/gmp/gmp.c
index fc7f4fbe5640965c325bf055791b22d543ac6047,399749d3975ff5e6232499a24cb6d1ec1c822c56..86188e25f7b84c4ac325264ad86034efb9f9e147
@@@ -1037,6 -1096,118 +1063,118 @@@ ZEND_FUNCTION(gmp_init
  }
  /* }}} */
  
 -int gmp_import_export_validate(long size, long options, int *order, int *endian TSRMLS_DC)
++int gmp_import_export_validate(zend_long size, zend_long options, int *order, int *endian TSRMLS_DC)
+ {
+       if (size < 1) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                       "Word size must be positive, %ld given", size);
+               return FAILURE;
+       }
+       switch (options & (GMP_LSW_FIRST | GMP_MSW_FIRST)) {
+               case GMP_LSW_FIRST:
+                       *order = -1;
+                       break;
+               case GMP_MSW_FIRST:
+               case 0: /* default */
+                       *order = 1;
+                       break;
+               default:
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                               "Invalid options: Conflicting word orders");
+                       return FAILURE;
+       }
+       switch (options & (GMP_LITTLE_ENDIAN | GMP_BIG_ENDIAN | GMP_NATIVE_ENDIAN)) {
+               case GMP_LITTLE_ENDIAN:
+                       *endian = -1;
+                       break;
+               case GMP_BIG_ENDIAN:
+                       *endian = 1;
+                       break;
+               case GMP_NATIVE_ENDIAN:
+               case 0: /* default */
+                       *endian = 0;
+                       break;
+               default:
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                               "Invalid options: Conflicting word endianness");
+                       return FAILURE;
+       }
+       return SUCCESS;
+ }
+ /* {{{ proto GMP gmp_import(string data [, int word_size = 1, int options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN])
+    Imports a GMP number from a binary string */
+ ZEND_FUNCTION(gmp_import)
+ {
+       char *data;
 -      int data_len;
 -      long size = 1;
 -      long options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN;;
++      size_t data_len;
++      zend_long size = 1;
++      zend_long options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN;;
+       int order, endian;
+       mpz_ptr gmpnumber;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &data, &data_len, &size, &options) == FAILURE) {
+               return;
+       }
+       if (gmp_import_export_validate(size, options, &order, &endian TSRMLS_CC) == FAILURE) {
+               RETURN_FALSE;
+       }
+       if ((data_len % size) != 0) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING,
+                       "Input length must be a multiple of word size");
+               RETURN_FALSE;
+       }
+       INIT_GMP_RETVAL(gmpnumber);
+       mpz_import(gmpnumber, data_len / size, order, size, endian, 0, data);
+ }
+ /* }}} */
+ /* {{{ proto string gmp_export(GMP gmpnumber [, int word_size = 1, int options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN])
+    Exports a GMP number to a binary string */
+ ZEND_FUNCTION(gmp_export)
+ {
+       zval *gmpnumber_arg;
 -      long size = 1;
 -      long options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN;;
++      zend_long size = 1;
++      zend_long options = GMP_MSW_FIRST | GMP_NATIVE_ENDIAN;;
+       int order, endian;
+       mpz_ptr gmpnumber;
+       gmp_temp_t temp_a;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", &gmpnumber_arg, &size, &options) == FAILURE) {
+               return;
+       }
+       if (gmp_import_export_validate(size, options, &order, &endian TSRMLS_CC) == FAILURE) {
+               RETURN_FALSE;
+       }
+       FETCH_GMP_ZVAL(gmpnumber, gmpnumber_arg, temp_a);
+       if (mpz_sgn(gmpnumber) == 0) {
 -              ZVAL_STRING(return_value, "", 1);
++              RETURN_EMPTY_STRING();
+       } else {
+               size_t bits_per_word = size * 8;
+               size_t count = (mpz_sizeinbase(gmpnumber, 2) + bits_per_word - 1) / bits_per_word;
+               size_t out_len = count * size;
 -              char *out_string = emalloc(out_len + 1);
 -              mpz_export(out_string, NULL, order, size, endian, 0, gmpnumber);
 -              out_string[out_len] = '\0';
++              zend_string *out_string = zend_string_alloc(out_len, 0);
++              mpz_export(out_string->val, NULL, order, size, endian, 0, gmpnumber);
++              out_string->val[out_len] = '\0';
 -              ZVAL_STRINGL(return_value, out_string, out_len, 0);
++              RETURN_STR(out_string);
+       }
+       FREE_GMP_TEMP(temp_a);
+ }
+ /* }}} */
  /* {{{ proto int gmp_intval(mixed gmpnumber)
     Gets signed long value of GMP number */
  ZEND_FUNCTION(gmp_intval)